Working on ocr

This commit is contained in:
nikse.dk 2014-02-20 21:35:26 +01:00
parent 0228ffce04
commit 5252c9f970
4 changed files with 153 additions and 66 deletions

View File

@ -16,7 +16,6 @@ namespace Nikse.SubtitleEdit.Forms
List<bool> _italics = new List<bool>(); List<bool> _italics = new List<bool>();
internal List<VobSubOcr.ImageCompareAddition> Additions { get; private set; } internal List<VobSubOcr.ImageCompareAddition> Additions { get; private set; }
BinaryOcrDb _binOcrDb = null; BinaryOcrDb _binOcrDb = null;
List<BinaryOcrBitmap> _binOcrListLookups = null;
public XmlDocument ImageCompareDocument public XmlDocument ImageCompareDocument
{ {
@ -103,6 +102,18 @@ namespace Nikse.SubtitleEdit.Forms
} }
} }
} }
foreach (BinaryOcrBitmap bob in _binOcrDb.CompareImagesExpanded)
{
string name = bob.Key;
foreach (VobSubOcr.ImageCompareAddition a in additions)
{
if (name == a.Name && bob.Text != null)
{
listBoxFileNames.Items.Add(bob);
_italics.Add(bob.Italic);
}
}
}
} }
else else
{ {
@ -154,6 +165,13 @@ namespace Nikse.SubtitleEdit.Forms
texts.Add(text); texts.Add(text);
count++; count++;
} }
foreach (BinaryOcrBitmap bob in _binOcrDb.CompareImagesExpanded)
{
string text = bob.Text;
if (!texts.Contains(text) && text != null)
texts.Add(text);
count++;
}
} }
else else
{ {
@ -199,6 +217,15 @@ namespace Nikse.SubtitleEdit.Forms
_italics.Add(bob.Italic); _italics.Add(bob.Italic);
} }
} }
foreach (BinaryOcrBitmap bob in _binOcrDb.CompareImagesExpanded)
{
string text = bob.Text;
if (text == target)
{
listBoxFileNames.Items.Add(bob);
_italics.Add(bob.Italic);
}
}
} }
else else
{ {
@ -257,8 +284,10 @@ namespace Nikse.SubtitleEdit.Forms
{ {
var bob = GetSelectedBinOcrBitmap(); var bob = GetSelectedBinOcrBitmap();
if (bob != null) if (bob != null)
{
bmp = bob.ToOldBitmap(); bmp = bob.ToOldBitmap();
} }
}
else if (File.Exists(databaseName)) else if (File.Exists(databaseName))
{ {
using (var f = new FileStream(databaseName, FileMode.Open)) using (var f = new FileStream(databaseName, FileMode.Open))

View File

@ -2501,61 +2501,36 @@ namespace Nikse.SubtitleEdit.Forms
return null; return null;
} }
var bob = new BinaryOcrBitmap(target);
// build merged items - for expanded match search for (int k = 0; k < _binaryOcrDb.CompareImagesExpanded.Count; k++)
var mergedItems = new List<ImageSplitterItem>();
List<ImageSplitterItem> expandSelectionList = new List<ImageSplitterItem>();
for (int j = listIndex; j < list.Count; j++)
{ {
ImageSplitterItem item = list[j]; var b = _binaryOcrDb.CompareImagesExpanded[k];
if (item.NikseBitmap == null) if (bob.Hash == b.Hash && bob.Width == b.Width && bob.Height == b.Height && bob.NumberOfColoredPixels == b.NumberOfColoredPixels)
{ {
break; bool ok = false;
for (int i = 0; i < b.ExpandedList.Count; i++)
{
if (listIndex + i + 1 < list.Count && list[listIndex + i + 1].NikseBitmap != null && b.ExpandedList[i].Hash == new BinaryOcrBitmap(list[listIndex + i + 1].NikseBitmap).Hash)
{
ok = true;
} }
else else
{ {
expandSelectionList.Add(item); ok = false;
if (expandSelectionList.Count > 1 && expandSelectionList.Count < 10) break;
mergedItems.Add(GetExpandedSelectionNew(parentBitmap, expandSelectionList));
} }
} }
if (ok)
// check for expand match!
foreach (BinaryOcrBitmap compareItem in _binaryOcrDb.CompareImages)
{ {
if (compareItem.ExpandCount > 0 && secondBestGuess = null;
mergedItems.Count > 0 && return new CompareMatch(b.Text, b.Italic, b.ExpandCount, b.Key);
compareItem.Width > target.Width &&
parentBitmap.Width >= compareItem.Width + targetItem.X &&
parentBitmap.Height >= compareItem.Height)
{
foreach (ImageSplitterItem merged in mergedItems)
{
if (merged.NikseBitmap.Width == compareItem.Width && merged.NikseBitmap.Height == compareItem.Height)
{
int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem, merged.NikseBitmap);
if (dif < smallestDifference)
{
bool allow = true;
if (Math.Abs(target.Height - compareItem.Height) > 5 && compareItem.Text == "\"")
allow = false;
if (allow)
{
smallestDifference = dif;
smallestIndex = index;
if (dif == 0)
break; // foreach ending
} }
} }
} }
}
}
index++;
}
// Search images with minor location changes // Search images with minor location changes
FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, target, _binaryOcrDb); FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, target, _binaryOcrDb, bob);
if (maxDiff > 0) if (maxDiff > 0)
{ {
if (smallestDifference * 100.0 / (target.Width * target.Height) > _vobSubOcrSettings.AllowDifferenceInPercent && target.Width < 70) if (smallestDifference * 100.0 / (target.Width * target.Height) > _vobSubOcrSettings.AllowDifferenceInPercent && target.Width < 70)
@ -2563,20 +2538,20 @@ namespace Nikse.SubtitleEdit.Forms
if (smallestDifference > 2 && target.Width > 25) if (smallestDifference > 2 && target.Width > 25)
{ {
var cutBitmap = target.CopyRectangle(new Rectangle(4, 0, target.Width - 4, target.Height)); var cutBitmap = target.CopyRectangle(new Rectangle(4, 0, target.Width - 4, target.Height));
FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap, _binaryOcrDb); FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap, _binaryOcrDb, bob);
double differencePercentage = smallestDifference * 100.0 / (target.Width * target.Height); double differencePercentage = smallestDifference * 100.0 / (target.Width * target.Height);
} }
if (smallestDifference > 2 && target.Width > 12) if (smallestDifference > 2 && target.Width > 12)
{ {
var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height)); var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height));
FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap, _binaryOcrDb); FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap, _binaryOcrDb, bob);
} }
if (smallestDifference > 2 && target.Width > 12) if (smallestDifference > 2 && target.Width > 12)
{ {
var cutBitmap = target.CopyRectangle(new Rectangle(0, 0, target.Width - 2, target.Height)); var cutBitmap = target.CopyRectangle(new Rectangle(0, 0, target.Width - 2, target.Height));
FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap, _binaryOcrDb); FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap, _binaryOcrDb, bob);
} }
if (smallestDifference > 2 && target.Width > 12) if (smallestDifference > 2 && target.Width > 12)
@ -2585,7 +2560,7 @@ namespace Nikse.SubtitleEdit.Forms
int topCrop = 0; int topCrop = 0;
var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop, 2); var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop, 2);
if (cutBitmap2.Height != target.Height) if (cutBitmap2.Height != target.Height)
FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2, _binaryOcrDb); FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2, _binaryOcrDb, bob);
} }
if (smallestDifference > 2 && target.Width > 15) if (smallestDifference > 2 && target.Width > 15)
@ -2594,7 +2569,7 @@ namespace Nikse.SubtitleEdit.Forms
int topCrop = 0; int topCrop = 0;
var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop); var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop);
if (cutBitmap2.Height != target.Height) if (cutBitmap2.Height != target.Height)
FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2, _binaryOcrDb); FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2, _binaryOcrDb, bob);
} }
if (smallestDifference > 2 && target.Width > 15) if (smallestDifference > 2 && target.Width > 15)
@ -2603,7 +2578,7 @@ namespace Nikse.SubtitleEdit.Forms
int topCrop = 0; int topCrop = 0;
var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop); var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop);
if (cutBitmap2.Height != target.Height) if (cutBitmap2.Height != target.Height)
FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2, _binaryOcrDb); FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2, _binaryOcrDb, bob);
} }
} }
} }
@ -2655,9 +2630,8 @@ namespace Nikse.SubtitleEdit.Forms
return bmp; return bmp;
} }
private static void FindBestMatchNew(ref int index, ref int smallestDifference, ref int smallestIndex, NikseBitmap target, BinaryOcrDb binOcrDb) private static void FindBestMatchNew(ref int index, ref int smallestDifference, ref int smallestIndex, NikseBitmap target, BinaryOcrDb binOcrDb, BinaryOcrBitmap bob)
{ {
var bob = new BinaryOcrBitmap(target);
var bobExactMatch = binOcrDb.FindExactMatch(bob); var bobExactMatch = binOcrDb.FindExactMatch(bob);
if (bobExactMatch >= 0) if (bobExactMatch >= 0)
{ {
@ -3369,13 +3343,30 @@ namespace Nikse.SubtitleEdit.Forms
return name; return name;
} }
private string SaveCompareItemNew(NikseBitmap newTarget, string text, bool isItalic, int expandCount) private string SaveCompareItemNew(NikseBitmap newTarget, string text, bool isItalic, List<ImageSplitterItem> expandList)
{ {
BinaryOcrBitmap bob = new BinaryOcrBitmap(newTarget, isItalic, expandCount, text); int expandCount = 0;
if (expandList != null)
expandCount = expandList.Count;
if (expandCount > 0)
{
var bob = new BinaryOcrBitmap(expandList[0].NikseBitmap, isItalic, expandCount, text);
bob.ExpandedList = new List<BinaryOcrBitmap>();
for (int j = 1; j < expandList.Count; j++)
bob.ExpandedList.Add(new BinaryOcrBitmap(expandList[j].NikseBitmap));
_binaryOcrDb.Add(bob); _binaryOcrDb.Add(bob);
_binaryOcrDb.Save(); _binaryOcrDb.Save();
return bob.Key; return bob.Key;
} }
else
{
var bob = new BinaryOcrBitmap(newTarget, isItalic, expandCount, text);
_binaryOcrDb.Add(bob);
_binaryOcrDb.Save();
return bob.Key;
}
}
/// <summary> /// <summary>
/// Ocr via image compare /// Ocr via image compare
@ -3632,7 +3623,7 @@ namespace Nikse.SubtitleEdit.Forms
else if (result == DialogResult.OK) else if (result == DialogResult.OK)
{ {
string text = _vobSubOcrCharacter.ManualRecognizedCharacters; string text = _vobSubOcrCharacter.ManualRecognizedCharacters;
string name = SaveCompareItemNew(item.NikseBitmap, text, _vobSubOcrCharacter.IsItalic, expandSelectionList.Count); string name = SaveCompareItemNew(item.NikseBitmap, text, _vobSubOcrCharacter.IsItalic, expandSelectionList);
var addition = new ImageCompareAddition(name, text, item.NikseBitmap, _vobSubOcrCharacter.IsItalic, listViewIndex); var addition = new ImageCompareAddition(name, text, item.NikseBitmap, _vobSubOcrCharacter.IsItalic, listViewIndex);
_lastAdditions.Add(addition); _lastAdditions.Add(addition);
matches.Add(new CompareMatch(text, _vobSubOcrCharacter.IsItalic, expandSelectionList.Count, null)); matches.Add(new CompareMatch(text, _vobSubOcrCharacter.IsItalic, expandSelectionList.Count, null));
@ -3670,7 +3661,7 @@ namespace Nikse.SubtitleEdit.Forms
else if (result == DialogResult.OK) else if (result == DialogResult.OK)
{ {
string text = _vobSubOcrCharacter.ManualRecognizedCharacters; string text = _vobSubOcrCharacter.ManualRecognizedCharacters;
string name = SaveCompareItemNew(item.NikseBitmap, text, _vobSubOcrCharacter.IsItalic, 0); string name = SaveCompareItemNew(item.NikseBitmap, text, _vobSubOcrCharacter.IsItalic, null);
var addition = new ImageCompareAddition(name, text, item.NikseBitmap, _vobSubOcrCharacter.IsItalic, listViewIndex); var addition = new ImageCompareAddition(name, text, item.NikseBitmap, _vobSubOcrCharacter.IsItalic, listViewIndex);
_lastAdditions.Add(addition); _lastAdditions.Add(addition);
matches.Add(new CompareMatch(text, _vobSubOcrCharacter.IsItalic, 0, null)); matches.Add(new CompareMatch(text, _vobSubOcrCharacter.IsItalic, 0, null));

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
@ -27,6 +28,7 @@ namespace Nikse.SubtitleEdit.Logic.OCR.Binary
public int ExpandCount { get; set; } public int ExpandCount { get; set; }
public bool LoadedOK { get; private set; } public bool LoadedOK { get; private set; }
public string Text { get; set; } public string Text { get; set; }
public List<BinaryOcrBitmap> ExpandedList { get; set; }
public string Key public string Key
{ {

View File

@ -8,6 +8,7 @@ namespace Nikse.SubtitleEdit.Logic.OCR.Binary
{ {
public string FileName { get; private set; } public string FileName { get; private set; }
public List<BinaryOcrBitmap> CompareImages = new List<BinaryOcrBitmap>(); public List<BinaryOcrBitmap> CompareImages = new List<BinaryOcrBitmap>();
public List<BinaryOcrBitmap> CompareImagesExpanded = new List<BinaryOcrBitmap>();
public BinaryOcrDb(string fileName) public BinaryOcrDb(string fileName)
{ {
@ -29,6 +30,12 @@ namespace Nikse.SubtitleEdit.Logic.OCR.Binary
{ {
foreach (var bob in CompareImages) foreach (var bob in CompareImages)
bob.Save(gz); bob.Save(gz);
foreach (var bob in CompareImagesExpanded)
{
bob.Save(gz);
foreach (var ExpandedBob in bob.ExpandedList)
ExpandedBob.Save(gz);
}
gz.Flush(); gz.Flush();
gz.Close(); gz.Close();
} }
@ -38,6 +45,7 @@ namespace Nikse.SubtitleEdit.Logic.OCR.Binary
public void LoadCompareImages() public void LoadCompareImages()
{ {
var list = new List<BinaryOcrBitmap>(); var list = new List<BinaryOcrBitmap>();
var expandList = new List<BinaryOcrBitmap>();
if (!File.Exists(FileName)) if (!File.Exists(FileName))
{ {
@ -54,13 +62,34 @@ namespace Nikse.SubtitleEdit.Logic.OCR.Binary
{ {
var bob = new BinaryOcrBitmap(gz); var bob = new BinaryOcrBitmap(gz);
if (bob.LoadedOK) if (bob.LoadedOK)
list.Add(bob); {
if (bob.ExpandCount > 0)
{
expandList.Add(bob);
bob.ExpandedList = new List<BinaryOcrBitmap>();
for (int i = 1; i < bob.ExpandCount; i++)
{
var expandedBob = new BinaryOcrBitmap(gz);
if (expandedBob.LoadedOK)
bob.ExpandedList.Add(expandedBob);
else else
break;
}
}
else
{
list.Add(bob);
}
}
else
{
done = true; done = true;
} }
} }
} }
}
CompareImages = list; CompareImages = list;
CompareImagesExpanded = expandList;
} }
public int FindExactMatch(BinaryOcrBitmap bob) public int FindExactMatch(BinaryOcrBitmap bob)
@ -74,13 +103,49 @@ namespace Nikse.SubtitleEdit.Logic.OCR.Binary
return -1; return -1;
} }
public int FindExactMatchExpanded(BinaryOcrBitmap bob)
{
for (int i = 0; i < CompareImagesExpanded.Count; i++)
{
var b = CompareImagesExpanded[i];
if (bob.Hash == b.Hash && bob.Width == b.Width && bob.Height == b.Height && bob.NumberOfColoredPixels == b.NumberOfColoredPixels)
return i;
}
return -1;
}
public int Add(BinaryOcrBitmap bob) public int Add(BinaryOcrBitmap bob)
{ {
int index = FindExactMatch(bob); int index;
if (bob.ExpandCount > 0)
{
index = FindExactMatchExpanded(bob);
if (index == -1 || CompareImagesExpanded[index].ExpandCount != bob.ExpandCount)
{
CompareImagesExpanded.Add(bob);
}
else
{
bool allAlike = true;
for (int i=0; i < bob.ExpandCount-1; i++)
{
if (bob.ExpandedList[i].Hash != CompareImagesExpanded[index].ExpandedList[i].Hash)
allAlike = false;
}
if (!allAlike)
CompareImages.Add(bob);
else
System.Windows.Forms.MessageBox.Show("Expanded image already in db!");
}
}
else
{
index = FindExactMatch(bob);
if (index == -1) if (index == -1)
CompareImages.Add(bob); CompareImages.Add(bob);
else else
System.Windows.Forms.MessageBox.Show("Image already in db!"); System.Windows.Forms.MessageBox.Show("Image already in db!");
}
return index; return index;
} }