internal void Initialize(Bitmap vobSubImage, ImageSplitterItem character, Point position, bool italicChecked, bool showShrink) { 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; _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(); }
internal void Initialize(Bitmap vobSubImage, ImageSplitterItem character, Point position, bool italicChecked, bool showShrink, VobSubOcr.CompareMatch bestGuess, List<VobSubOcr.ImageCompareAddition> additions, VobSubOcr vobSubForm) { 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; }
private static IEnumerable <ImageSplitterItem> SplitHorizontalNew(ImageSplitterItem lineSplitterItem, int xOrMorePixelsMakesSpace) { var bmp = new NikseBitmap(lineSplitterItem.NikseBitmap); bmp.AddTransparentLineRight(); var parts = new List <ImageSplitterItem>(); int startX = 0; int width = 0; int spacePixels = 0; int subtractSpacePixels = 0; for (int x = 0; x < bmp.Width; x++) { bool right; bool clean; List <Point> points = IsVerticalLineTransparetNew(bmp, x, out right, out clean); if (points != null && clean) { spacePixels++; } if (right && points != null) { int add = FindMaxX(points, x) - x; width += add; subtractSpacePixels = add; } var newStartX = points != null?FindMinX(points, x) : 0; if (points == null) { width++; } else if (width > 0 && newStartX > startX + 1) { var bmp0 = new NikseBitmap(bmp); // remove pixels after current; for (int index = 0; index < points.Count; index++) { var p = points[index]; bmp0.MakeVerticalLinePartTransparent(p.X, p.X + index, p.Y); } width = FindMaxX(points, x) - startX; width--; startX++; var b1 = bmp0.CopyRectangle(new Rectangle(startX, 0, width, bmp.Height)); int addY; b1 = CropTopAndBottom(b1, out addY); if (spacePixels >= xOrMorePixelsMakesSpace && parts.Count > 0) { parts.Add(new ImageSplitterItem(" ") { Y = addY + lineSplitterItem.Y }); } if (b1.Width > 0 && b1.Height > 0) { parts.Add(new ImageSplitterItem(startX + lineSplitterItem.X, addY + lineSplitterItem.Y, b1)); //y is what? } // remove pixels before next letter; const int begin = 0; foreach (var p in points) { bmp.MakeVerticalLinePartTransparent(begin, p.X, p.Y); } width = 1; startX = FindMinX(points, x); spacePixels = -subtractSpacePixels; subtractSpacePixels = 0; } else if (clean) { width = 1; startX = newStartX; } } return(parts); }
private static List <ImageSplitterItem> SplitHorizontal(ImageSplitterItem verticalItem, int xOrMorePixelsMakesSpace) { // split line into letters NikseBitmap bmp = verticalItem.NikseBitmap; var parts = new List <ImageSplitterItem>(); int size = 0; int startX = 0; int lastEndX = 0; bool spaceJustAdded = false; for (int x = 0; x < bmp.Width - 1; x++) { int y; bool allTransparent = IsVerticalLineTransparent(bmp, out y, x); // check if line is transparent and cursive bool cursiveOk = false; int tempY; if (allTransparent == false && size > 5 && y > 3 && x < bmp.Width - 2 && !IsVerticalLineTransparent(bmp, out tempY, x + 1)) { //Add space? if (lastEndX > 0 && lastEndX + xOrMorePixelsMakesSpace < startX) { int cleanCount = 0; for (int j = lastEndX; j < startX; j++) { if (IsVerticalLineTransparentAlphaOnly(bmp, j)) { cleanCount++; } } if (cleanCount > 0 && !spaceJustAdded) { parts.Add(new ImageSplitterItem(" ")); spaceJustAdded = true; } } var cursivePoints = new List <Point>(); cursiveOk = IsCursiveVerticalLineTransparent(bmp, size, y, x, cursivePoints); if (cursiveOk) { // make letter image int end = x + 1 - startX; if (startX > 0) { startX--; end++; } NikseBitmap b1 = bmp.CopyRectangle(new Rectangle(startX, 0, end, bmp.Height)); // b1.Save(@"d:\temp\cursive.bmp"); // just for debugging // make non-black/transparent stuff from other letter transparent foreach (Point p in cursivePoints) { for (int fixY = p.Y; fixY < bmp.Height; fixY++) { b1.SetPixel(p.X - startX, fixY, Color.Transparent); } } RemoveBlackBarRight(b1); // b1.Save(@"d:\temp\cursive-cleaned.bmp"); // just for debugging // crop and save image int addY; b1 = CropTopAndBottom(b1, out addY); parts.Add(new ImageSplitterItem(startX, verticalItem.Y + addY, b1)); spaceJustAdded = false; size = 0; startX = x + 1; lastEndX = x; } } if (!cursiveOk) { if (allTransparent) { if (size > 0) { if (size > 1) { //Add space? if (lastEndX > 0 && lastEndX + xOrMorePixelsMakesSpace < startX) { int cleanCount = 0; for (int j = lastEndX; j < startX; j++) { if (IsVerticalLineTransparentAlphaOnly(bmp, j)) { cleanCount++; } } if (cleanCount > 2 && !spaceJustAdded) { parts.Add(new ImageSplitterItem(" ")); } } if (startX > 0) { startX--; } lastEndX = x; int end = x + 1 - startX; NikseBitmap part = bmp.CopyRectangle(new Rectangle(startX, 0, end, bmp.Height)); RemoveBlackBarRight(part); int addY; // part.Save("c:\\before" + startX.ToString() + ".bmp"); // just for debugging part = CropTopAndBottom(part, out addY); // part.Save("c:\\after" + startX.ToString() + ".bmp"); // just for debugging parts.Add(new ImageSplitterItem(startX, verticalItem.Y + addY, part)); spaceJustAdded = false; // part.Save(@"d:\temp\cursive.bmp"); // just for debugging } size = 0; } startX = x + 1; } else { size++; } } } if (size > 0) { if (lastEndX > 0 && lastEndX + xOrMorePixelsMakesSpace < startX && !spaceJustAdded) { parts.Add(new ImageSplitterItem(" ")); } if (startX > 0) { startX--; } lastEndX = bmp.Width - 1; int end = lastEndX + 1 - startX; NikseBitmap part = bmp.CopyRectangle(new Rectangle(startX, 0, end, bmp.Height - 1)); int addY; part = CropTopAndBottom(part, out addY); parts.Add(new ImageSplitterItem(startX, verticalItem.Y + addY, part)); //part.Save(@"d:\temp\cursive.bmp"); // just for debugging } return(parts); }
internal CompareMatch GetNOcrCompareMatch(ImageSplitterItem targetItem, NikseBitmap parentBitmap, NOcrDb nOcrDb, double unItalicFactor, bool tryItalicScaling, bool deepSeek) { bool italic; var expandedResult = NOcrFindExpandedMatch(parentBitmap, targetItem, targetItem.Y - targetItem.ParentY, nOcrDb.OcrCharacters); if (expandedResult != null) return new CompareMatch(expandedResult.Text, expandedResult.Italic, expandedResult.ExpandCount, null, expandedResult); var result = NOcrFindBestMatchNew(parentBitmap, targetItem, targetItem.Y - targetItem.ParentY, out italic, nOcrDb, unItalicFactor, tryItalicScaling, deepSeek); if (result == null) { if (checkBoxNOcrCorrect.Checked) return null; else return new CompareMatch("*", false, 0, null); } // Fix uppercase/lowercase issues (not I/l) if (result.Text == "e") _nocrLastLowercaseHeight = targetItem.NikseBitmap.Height; else if (_nocrLastLowercaseHeight == -1 && result.Text == "a") _nocrLastLowercaseHeight = targetItem.NikseBitmap.Height; if (result.Text == "E" || result.Text == "H" || result.Text == "R" || result.Text == "D" || result.Text == "T") _nocrLastUppercaseHeight = targetItem.NikseBitmap.Height; else if (_nocrLastUppercaseHeight == -1 && result.Text == "M") _nocrLastUppercaseHeight = targetItem.NikseBitmap.Height; if (result.Text == "V" || result.Text == "W" || result.Text == "U" || result.Text == "S" || result.Text == "Z" || result.Text == "O" || result.Text == "X" || result.Text == "Ø" || result.Text == "C") { if (_nocrLastLowercaseHeight > 3 && targetItem.NikseBitmap.Height - _nocrLastLowercaseHeight < 2) result.Text = result.Text.ToLower(); } else if (result.Text == "v" || result.Text == "w" || result.Text == "u" || result.Text == "s" || result.Text == "z" || result.Text == "o" || result.Text == "x" || result.Text == "ø" || result.Text == "c") { if (_nocrLastUppercaseHeight > 3 && _nocrLastUppercaseHeight - targetItem.NikseBitmap.Height < 2) result.Text = result.Text.ToUpper(); } if (italic) return new CompareMatch(result.Text, true, 0, null, result); else return new CompareMatch(result.Text, result.Italic, 0, null, result); }
internal static CompareMatch GetNOcrCompareMatch(ImageSplitterItem targetItem, NikseBitmap parentBitmap, NOcrThreadParameter p) { bool italic; var expandedResult = NOcrFindExpandedMatch(parentBitmap, targetItem, targetItem.Y - targetItem.ParentY, p.NOcrChars); if (expandedResult != null) return new CompareMatch(expandedResult.Text, expandedResult.Italic, expandedResult.ExpandCount, null, expandedResult); var result = NOcrFindBestMatch(parentBitmap, targetItem, targetItem.Y - targetItem.ParentY, out italic, p.NOcrChars, p.UnItalicFactor, p.AdvancedItalicDetection, true); if (result == null) return null; // Fix uppercase/lowercase issues (not I/l) if (result.Text == "e") p.NOcrLastLowercaseHeight = targetItem.NikseBitmap.Height; else if (p.NOcrLastLowercaseHeight == -1 && result.Text == "a") p.NOcrLastLowercaseHeight = targetItem.NikseBitmap.Height; if (result.Text == "E" || result.Text == "H" || result.Text == "R" || result.Text == "D" || result.Text == "T") p.NOcrLastUppercaseHeight = targetItem.NikseBitmap.Height; else if (p.NOcrLastUppercaseHeight == -1 && result.Text == "M") p.NOcrLastUppercaseHeight = targetItem.NikseBitmap.Height; if (result.Text == "V" || result.Text == "W" || result.Text == "U" || result.Text == "S" || result.Text == "Z" || result.Text == "O" || result.Text == "X" || result.Text == "Ø" || result.Text == "C") { if (p.NOcrLastLowercaseHeight > 3 && targetItem.NikseBitmap.Height - p.NOcrLastLowercaseHeight < 2) result.Text = result.Text.ToLower(); } else if (result.Text == "v" || result.Text == "w" || result.Text == "u" || result.Text == "s" || result.Text == "z" || result.Text == "o" || result.Text == "x" || result.Text == "ø" || result.Text == "c") { if (p.NOcrLastUppercaseHeight > 3 && p.NOcrLastUppercaseHeight - targetItem.NikseBitmap.Height < 2) result.Text = result.Text.ToUpper(); } if (italic) return new CompareMatch(result.Text, true, 0, null, result); else return new CompareMatch(result.Text, result.Italic, 0, null, result); }
public CompareMatch(string text, bool italic, int expandCount, string name, ImageSplitterItem imageSplitterItem) : this(text, italic, expandCount, name) { ImageSplitterItem = imageSplitterItem; }
private string SaveCompareItemNew(ImageSplitterItem newTarget, string text, bool isItalic, List<ImageSplitterItem> expandList) { int expandCount = 0; if (expandList != null) expandCount = expandList.Count; if (expandCount > 0) { var bob = new BinaryOcrBitmap(expandList[0].NikseBitmap, isItalic, expandCount, text, expandList[0].X, expandList[0].Y); bob.ExpandedList = new List<BinaryOcrBitmap>(); for (int j = 1; j < expandList.Count; j++) { var expandedBob = new BinaryOcrBitmap(expandList[j].NikseBitmap); expandedBob.X = expandList[j].X; expandedBob.Y = expandList[j].Y; bob.ExpandedList.Add(expandedBob); } _binaryOcrDb.Add(bob); _binaryOcrDb.Save(); return bob.Key; } else { var bob = new BinaryOcrBitmap(newTarget.NikseBitmap, isItalic, expandCount, text, newTarget.X, newTarget.Y); _binaryOcrDb.Add(bob); _binaryOcrDb.Save(); return bob.Key; } }
/// <summary> /// split into lines /// </summary> public static List <ImageSplitterItem> SplitToLinesNew(ImageSplitterItem item, int minLineHeight, double averageLineHeight = -1) { var bmp = new NikseBitmap(item.NikseBitmap); var parts = new List <ImageSplitterItem>(); bool started = false; var splitLines = new Dictionary <int, List <Point> >(); var startY = 0; for (int y = minLineHeight; y < bmp.Height - minLineHeight; y++) { if (startY == y && bmp.IsLineTransparent(y)) { startY++; continue; } var points = new List <Point>(); var yChange = 0; var completed = false; var backJump = 0; int x = 0; var maxUp = Math.Min(10, minLineHeight / 2); while (x < bmp.Width) { var a1 = bmp.GetAlpha(x, y + yChange); var a2 = bmp.GetAlpha(x, y + 1 + yChange); if (a1 > 150 || a2 > 150) { if (x > 1 && yChange < 8 && bmp.GetAlpha(x - 1, y + yChange) < 150 && bmp.GetAlpha(x - 1, y + yChange) < 150 && bmp.GetAlpha(x - 1, y + 1 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 2 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 2 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 3 + yChange) < 150 && bmp.GetAlpha(x, y + 2 + yChange) < 150 && bmp.GetAlpha(x, y + 3 + yChange) < 150) { yChange += 2; } else if (x > 1 && yChange < 8 && bmp.GetAlpha(x - 1, y + yChange) < 150 && bmp.GetAlpha(x - 1, y + yChange) < 150 && bmp.GetAlpha(x - 1, y + 1 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 2 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 2 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 3 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 3 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 4 + yChange) < 150 && bmp.GetAlpha(x, y + 3 + yChange) < 150 && bmp.GetAlpha(x, y + 4 + yChange) < 150) { yChange += 3; } else if (x > 1 && yChange < 7 && bmp.GetAlpha(x - 1, y + yChange) < 150 && bmp.GetAlpha(x - 1, y + yChange) < 150 && bmp.GetAlpha(x - 1, y + 1 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 2 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 2 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 3 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 3 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 4 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 4 + yChange) < 150 && bmp.GetAlpha(x - 1, y + 5 + yChange) < 150 && bmp.GetAlpha(x, y + 4 + yChange) < 150 && bmp.GetAlpha(x, y + 5 + yChange) < 150) { yChange += 4; } else if (x > 1 && yChange > -7 && bmp.GetAlpha(x - 1, y + yChange) < 150 && bmp.GetAlpha(x - 1, y + yChange) < 150 && bmp.GetAlpha(x - 1, y - 1 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 2 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 2 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 3 + yChange) < 150 && bmp.GetAlpha(x, y - 2 + yChange) < 150 && bmp.GetAlpha(x, y - 3 + yChange) < 150) { yChange -= 2; } else if (x > 1 && yChange > -7 && bmp.GetAlpha(x - 1, y + yChange) < 150 && bmp.GetAlpha(x - 1, y + yChange) < 150 && bmp.GetAlpha(x - 1, y - 1 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 2 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 2 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 3 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 3 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 4 + yChange) < 150 && bmp.GetAlpha(x, y - 3 + yChange) < 150 && bmp.GetAlpha(x, y - 4 + yChange) < 150) { yChange -= 3; } else if (x > 1 && yChange > -7 && bmp.GetAlpha(x - 1, y + yChange) < 150 && bmp.GetAlpha(x - 1, y + yChange) < 150 && bmp.GetAlpha(x - 1, y - 1 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 2 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 2 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 3 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 3 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 4 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 4 + yChange) < 150 && bmp.GetAlpha(x - 1, y - 5 + yChange) < 150 && bmp.GetAlpha(x, y - 4 + yChange) < 150 && bmp.GetAlpha(x, y - 5 + yChange) < 150) { yChange -= 4; } else if (x > 10 && backJump < 3 && x > 5 && yChange > -7) // go left + up + check 12 pixels right { var done = false; for (int i = 1; i < maxUp; i++) { for (int k = 1; k < 9; k++) { if (CanGoUpAndRight(bmp, i, 12, x - k, y + yChange, minLineHeight)) { backJump++; x -= k; points.RemoveAll(p => p.X > x); done = true; yChange -= (i + 1); break; } } if (done) { break; } } if (!done) { started = true; break; } } else { started = true; break; } } if (started) { points.Add(new Point(x, y + yChange)); } completed = x == bmp.Width - 1; x++; } if (completed) { splitLines.Add(y, points); } } var transparentColor = Color.FromArgb(0, 0, 0, 0); foreach (var line in splitLines) { var key = line.Key; if (key - startY > minLineHeight && line.Value.Count > 0) { var maxY = line.Value.Max(p => p.Y); var part = bmp.CopyRectangle(new Rectangle(0, startY, bmp.Width, maxY - startY)); //part.GetBitmap().Save(@"j:\temp\split_" + parts.Count + "_before.bmp"); foreach (var point in line.Value) { // delete down for (var y = point.Y - 1; y < startY + part.Height; y++) { part.SetPixel(point.X, y - startY, transparentColor); } } //part.GetBitmap().Save(@"j:\temp\split_" + parts.Count + "_after.bmp"); if (!part.IsImageOnlyTransparent() && part.GetNonTransparentHeight() >= minLineHeight) { var minY = line.Value.Min(p => p.Y); // bmp.GetBitmap().Save(@"j:\temp\main_" + parts.Count + "_before.bmp"); foreach (var point in line.Value) { // delete up for (var y = point.Y; y >= minY; y--) { bmp.SetPixel(point.X, y, transparentColor); } } // bmp.GetBitmap().Save(@"j:\temp\main_" + parts.Count + "_after.bmp"); // part.GetBitmap().Save(@"j:\temp\split_" + parts.Count + "_after.bmp"); var croppedTop = part.CropTopTransparent(0); parts.Add(new ImageSplitterItem(0 + item.X, startY + croppedTop + item.Y, part)); startY = key + 1; } } } if (bmp.Height - startY > 1 && parts.Count > 0) { var part = bmp.CopyRectangle(new Rectangle(0, startY, bmp.Width, bmp.Height - startY)); if (!part.IsImageOnlyTransparent()) { //part.GetBitmap().Save(@"j:\temp\split_" + parts.Count + ".bmp"); var croppedTop = part.CropTopTransparent(0); parts.Add(new ImageSplitterItem(0 + item.X, startY + croppedTop + item.Y, part)); } } if (parts.Count <= 1) { return(new List <ImageSplitterItem> { item }); } return(parts); }
private CompareMatch GetCompareMatch(ImageSplitterItem targetItem, NikseBitmap parentBitmap, out CompareMatch secondBestGuess, List<ImageSplitterItem> list, int listIndex) { secondBestGuess = null; int index = 0; int smallestDifference = 10000; int smallestIndex = -1; NikseBitmap target = targetItem.NikseBitmap; if (_compareBitmaps == null) { secondBestGuess = null; return null; } foreach (CompareItem compareItem in _compareBitmaps) { // check for expand match! if (compareItem.ExpandCount > 0 && compareItem.Bitmap.Width > target.Width && parentBitmap.Width >= compareItem.Bitmap.Width + targetItem.X) // && parentBitmap.Height >= compareItem.Bitmap.Height + targetItem.Y) //NIXE-debug-test- what not correct? { int minY = targetItem.Y; for (int j = 1; j < compareItem.ExpandCount; j++) { if (list != null && list.Count > listIndex + j && list[listIndex + j].Y < minY) minY = list[listIndex + j].Y; } if (parentBitmap.Height >= compareItem.Bitmap.Height + minY) { var cutBitmap = parentBitmap.CopyRectangle(new Rectangle(targetItem.X, minY, compareItem.Bitmap.Width, compareItem.Bitmap.Height)); int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem.Bitmap, cutBitmap); if (dif < smallestDifference) { bool allow = true; if (Math.Abs(target.Height - compareItem.Bitmap.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 FindBestMatch(ref index, ref smallestDifference, ref smallestIndex, target, _compareBitmaps); if (smallestDifference * 100.0 / (target.Width * target.Height) > _vobSubOcrSettings.AllowDifferenceInPercent && target.Width < 70) { if (smallestDifference > 2 && target.Width > 25) { var cutBitmap = target.CopyRectangle(new Rectangle(4, 0, target.Width - 4, target.Height)); FindBestMatch(ref index, ref smallestDifference, ref smallestIndex, cutBitmap, _compareBitmaps); double differencePercentage = smallestDifference * 100.0 / (target.Width * target.Height); } if (smallestDifference > 2 && target.Width > 12) { var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height)); FindBestMatch(ref index, ref smallestDifference, ref smallestIndex, cutBitmap, _compareBitmaps); } if (smallestDifference > 2 && target.Width > 12) { var cutBitmap = target.CopyRectangle(new Rectangle(0, 0, target.Width - 2, target.Height)); FindBestMatch(ref index, ref smallestDifference, ref smallestIndex, cutBitmap, _compareBitmaps); } if (smallestDifference > 2 && target.Width > 12) { var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height)); int topCrop = 0; var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop, 2); if (cutBitmap2.Height != target.Height) FindBestMatch(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2, _compareBitmaps); } if (smallestDifference > 2 && target.Width > 15) { var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height)); int topCrop = 0; var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop); if (cutBitmap2.Height != target.Height) FindBestMatch(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2, _compareBitmaps); } if (smallestDifference > 2 && target.Width > 15) { var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height)); int topCrop = 0; var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop); if (cutBitmap2.Height != target.Height) FindBestMatch(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2, _compareBitmaps); } } if (smallestIndex >= 0) { double differencePercentage = smallestDifference * 100.0 / (target.Width * target.Height); double maxDiff = (double)numericUpDownMaxErrorPct.Value; if (differencePercentage <= maxDiff) { var hit = _compareBitmaps[smallestIndex]; return new CompareMatch(hit.Text, hit.Italic, hit.ExpandCount, hit.Name); } var guess = _compareBitmaps[smallestIndex]; secondBestGuess = new CompareMatch(guess.Text, guess.Italic, guess.ExpandCount, guess.Name); } return null; }
private static NOcrChar NOcrFindExpandedMatch(NikseBitmap nbmp, ImageSplitterItem targetItem, int topMargin, List<NOcrChar> nOcrChars) { // var nbmp = new NikseBitmap(parentBitmap); int w = targetItem.NikseBitmap.Width; int index = 0; foreach (NOcrChar oc in nOcrChars) { if (oc.ExpandCount > 1 && oc.Width > w && targetItem.X + oc.Width < nbmp.Width) { bool ok = true; index = 0; while (index < oc.LinesForeground.Count && ok) { NOcrPoint op = oc.LinesForeground[index]; foreach (Point point in op.GetPoints(oc.Width, oc.Height)) { Point p = new Point(point.X + targetItem.X, point.Y + targetItem.Y); if (p.X >= 0 && p.Y >= 0 && p.X < nbmp.Width && p.Y < nbmp.Height) { Color c = nbmp.GetPixel(p.X, p.Y); if (c.A > 150 && c.R + c.G + c.B > NocrMinColor) { } else { ok = false; break; } } } index++; } index = 0; while (index < oc.LinesBackground.Count && ok) { NOcrPoint op = oc.LinesBackground[index]; foreach (Point point in op.GetPoints(oc.Width, oc.Height)) { Point p = new Point(point.X + targetItem.X, point.Y + targetItem.Y); if (p.X >= 0 && p.Y >= 0 && p.X < nbmp.Width && p.Y < nbmp.Height) { Color c = nbmp.GetPixel(p.X, p.Y); if (c.A > 150 && c.R + c.G + c.B > NocrMinColor) { ok = false; break; } } } index++; } if (ok) return oc; ok = true; index = 0; while (index < oc.LinesForeground.Count && ok) { NOcrPoint op = oc.LinesForeground[index]; foreach (Point point in op.ScaledGetPoints(oc, oc.Width, oc.Height - 1)) { Point p = new Point(point.X + targetItem.X, point.Y + targetItem.Y); if (p.X >= 0 && p.Y >= 0 && p.X < nbmp.Width && p.Y < nbmp.Height) { Color c = nbmp.GetPixel(p.X, p.Y); if (c.A > 150 && c.R + c.G + c.B > NocrMinColor) { } else { ok = false; break; } } } index++; } index = 0; while (index < oc.LinesBackground.Count && ok) { NOcrPoint op = oc.LinesBackground[index]; foreach (Point point in op.ScaledGetPoints(oc, oc.Width, oc.Height - 1)) { Point p = new Point(point.X + targetItem.X, point.Y + targetItem.Y); if (p.X >= 0 && p.Y >= 0 && p.X < nbmp.Width && p.Y < nbmp.Height) { Color c = nbmp.GetPixel(p.X, p.Y); if (c.A > 150 && c.R + c.G + c.B > NocrMinColor) { ok = false; break; } } } index++; } if (ok) return oc; } } return null; }
private static NOcrChar NOcrFindBestMatchNew(NikseBitmap parentBitmap, ImageSplitterItem targetItem, int topMargin, out bool italic, NOcrDb nOcrDb, double unItalicFactor, bool tryItalicScaling, bool deepSeek) { italic = false; var nbmp = targetItem.NikseBitmap; int index = 0; foreach (NOcrChar oc in nOcrDb.OcrCharacters) { if (Math.Abs(oc.Width - nbmp.Width) < 3 && Math.Abs(oc.Height - nbmp.Height) < 3 && Math.Abs(oc.MarginTop - topMargin) < 3) { // only very accurate matches bool ok = true; index = 0; while (index < oc.LinesForeground.Count && ok) { NOcrPoint op = oc.LinesForeground[index]; foreach (Point point in op.ScaledGetPoints(oc, 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 + c.G + c.B > NocrMinColor) { } else { Point p = new Point(point.X - 1, point.Y); if (p.X < 0) p.X = 1; c = nbmp.GetPixel(p.X, p.Y); if (nbmp.Width > 20 && c.A > 150 && c.R + c.G + c.B > NocrMinColor) { } else { ok = false; break; } } } } index++; } index = 0; while (index < oc.LinesBackground.Count && ok) { NOcrPoint op = oc.LinesBackground[index]; foreach (Point point in op.ScaledGetPoints(oc, 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 + c.G + c.B > NocrMinColor) { Point p = new Point(point.X, point.Y); if (oc.Width > 19 && point.X > 0) p.X = p.X - 1; c = nbmp.GetPixel(p.X, p.Y); if (c.A > 150 && c.R + c.G + c.B > NocrMinColor) { ok = false; break; } } } } index++; } if (ok) return oc; } } foreach (NOcrChar oc in nOcrDb.OcrCharacters) { int marginTopDiff = Math.Abs(oc.MarginTop - topMargin); if (Math.Abs(oc.Width - nbmp.Width) < 4 && Math.Abs(oc.Height - nbmp.Height) < 4 && marginTopDiff > 4 && marginTopDiff < 9) { // only very accurate matches - but not for margin top bool ok = true; index = 0; while (index < oc.LinesForeground.Count && ok) { NOcrPoint op = oc.LinesForeground[index]; foreach (Point point in op.ScaledGetPoints(oc, 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 + c.G + c.B > NocrMinColor) { } else { ok = false; break; } } } index++; } index = 0; while (index < oc.LinesBackground.Count && ok) { NOcrPoint op = oc.LinesBackground[index]; foreach (Point point in op.ScaledGetPoints(oc, 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 + c.G + c.B > NocrMinColor) { ok = false; break; } } } index++; } if (ok) return oc; } } // try some resize if aspect ratio is about the same double widthPercent = nbmp.Height * 100.0 / nbmp.Width; foreach (NOcrChar oc in nOcrDb.OcrCharacters) { if (!oc.IsSensitive) { if (Math.Abs(oc.WidthPercent - widthPercent) < 15 && oc.Width > 12 && oc.Height > 19 && nbmp.Width > 19 && nbmp.Height > 12 && Math.Abs(oc.MarginTop - topMargin) < nbmp.Height / 4) { bool ok = true; index = 0; while (index < oc.LinesForeground.Count && ok) { NOcrPoint op = oc.LinesForeground[index]; foreach (Point point in op.ScaledGetPoints(oc, 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 + c.G + c.B > NocrMinColor) { } else { ok = false; break; } } } index++; } index = 0; while (index < oc.LinesBackground.Count && ok) { NOcrPoint op = oc.LinesBackground[index]; foreach (Point point in op.ScaledGetPoints(oc, 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 + c.G + c.B > NocrMinColor) { ok = false; break; } } } index++; } if (ok) return oc; } } } if (deepSeek) // if we do now draw then just try anything... { widthPercent = nbmp.Height * 100.0 / nbmp.Width; foreach (NOcrChar oc in nOcrDb.OcrCharacters) { if (!oc.IsSensitive) { if (Math.Abs(oc.WidthPercent - widthPercent) < 40 && nbmp.Height > 11) // && oc.Height > 12 && oc.Width > 16 && nbmp.Width > 16 && nbmp.Height > 12 && Math.Abs(oc.MarginTop - topMargin) < 15) { bool ok = true; foreach (NOcrPoint op in oc.LinesForeground) { foreach (Point point in op.ScaledGetPoints(oc, 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 + c.G + c.B > NocrMinColor) { } else { ok = false; break; } } } } foreach (NOcrPoint op in oc.LinesBackground) { foreach (Point point in op.ScaledGetPoints(oc, 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 + c.G + c.B > NocrMinColor) { ok = false; break; } } } } if (ok) return oc; } } } foreach (NOcrChar oc in nOcrDb.OcrCharacters) { if (Math.Abs(oc.WidthPercent - widthPercent) < 40 && oc.Height > 12 && oc.Width > 19 && nbmp.Width > 19 && nbmp.Height > 12 && Math.Abs(oc.MarginTop - topMargin) < 15) { bool ok = true; foreach (NOcrPoint op in oc.LinesForeground) { foreach (Point point in op.ScaledGetPoints(oc, nbmp.Width - 3, 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 + c.G + c.B > NocrMinColor) { } else { ok = false; break; } } } } foreach (NOcrPoint op in oc.LinesBackground) { foreach (Point point in op.ScaledGetPoints(oc, nbmp.Width - 3, 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 + c.G + c.B > NocrMinColor) { ok = false; break; } } } } if (ok) return oc; } } foreach (NOcrChar oc in nOcrDb.OcrCharacters) { if (Math.Abs(oc.WidthPercent - widthPercent) < 40 && oc.Height > 12 && oc.Width > 19 && nbmp.Width > 19 && nbmp.Height > 12 && Math.Abs(oc.MarginTop - topMargin) < 15) { bool ok = true; foreach (NOcrPoint op in oc.LinesForeground) { foreach (Point point in op.ScaledGetPoints(oc, nbmp.Width, nbmp.Height - 4)) { if (point.X >= 0 && point.Y + 4 >= 0 && point.X < nbmp.Width && point.Y + 4 < nbmp.Height) { Color c = nbmp.GetPixel(point.X, point.Y + 4); if (c.A > 150 && c.R + c.G + c.B > NocrMinColor) { } else { ok = false; break; } } } } foreach (NOcrPoint op in oc.LinesBackground) { foreach (Point point in op.ScaledGetPoints(oc, nbmp.Width, nbmp.Height - 4)) { if (point.X >= 0 && point.Y + 4 >= 0 && point.X < nbmp.Width && point.Y + 4 < nbmp.Height) { Color c = nbmp.GetPixel(point.X, point.Y + 4); if (c.A > 150 && c.R + c.G + c.B > NocrMinColor) { ok = false; break; } } } } if (ok) return oc; } } } if (tryItalicScaling) { // int left = targetItem.X; // int width = targetItem.Bitmap.Width; // //if (left > 3) // //{ // // left -= 3; // // width += 3; // //} // var temp = ImageSplitter.Copy(parentBitmap, new Rectangle(left, targetItem.Y, width , targetItem.Bitmap.Height)); // var bitmap2 = UnItalic(temp, unItalicFactor); // //var nbmpUnItalic = new NikseBitmap(unItalicedBmp); // //nbmpUnItalic.ReplaceNonWhiteWithTransparent(); // //Bitmap bitmap2 = nbmpUnItalic.GetBitmap(); //// bitmap2.Save(@"D:\Download\__" + Guid.NewGuid().ToString() + ".bmp"); // var list = ImageSplitter.SplitBitmapToLetters(bitmap2, 10, false, false); // var matches = new List<NOcrChar>(); // bool unitalicOk = true; // foreach (var spi in list) // { // var m = NOcrFindBestMatch(parentBitmap, spi, topMargin, out italic, nOcrChars, unItalicFactor, false, true); // if (m == null) // { // if (spi.Bitmap.Width > 2) // { // unitalicOk = false; // break; // } // } // else // { // matches.Add(m); // } // } // if (unitalicOk && matches.Count > 0) // { // italic = true; // if (matches.Count == 1) // { // return matches[0]; // } // else if (matches.Count > 1) // { // NOcrChar c = new NOcrChar(matches[0]); // c.LinesBackground.Clear(); // c.LinesForeground.Clear(); // c.Text = string.Empty; // foreach (var m in matches) // c.Text += m.Text; // return c; // } // } } return null; }
internal void Initialize(Bitmap vobSubImage, ImageSplitterItem character, Point position, bool italicChecked, bool showShrink, VobSubOcr.CompareMatch bestGuess, List<VobSubOcr.ImageCompareAddition> additions, VobSubOcr vobSubForm) { ShrinkSelection = false; ExpandSelection = false; textBoxCharacters.Text = string.Empty; if (bestGuess != null) { buttonGuess.Visible = false; // hm... not too useful :( buttonGuess.Text = bestGuess.Text; } else { buttonGuess.Visible = false; } _vobSubForm = vobSubForm; _additions = additions; buttonShrinkSelection.Visible = showShrink; checkBoxItalic.Checked = italicChecked; if (position.X != -1 && position.Y != -1) { StartPosition = FormStartPosition.Manual; Left = position.X; Top = position.Y; } pictureBoxSubtitleImage.Image = vobSubImage; pictureBoxCharacter.Image = character.NikseBitmap.GetBitmap(); if (_additions.Count > 0) { var last = _additions[_additions.Count - 1]; buttonLastEdit.Visible = true; if (last.Italic) buttonLastEdit.Font = new System.Drawing.Font(buttonLastEdit.Font.FontFamily, buttonLastEdit.Font.Size, FontStyle.Italic); else buttonLastEdit.Font = new System.Drawing.Font(buttonLastEdit.Font.FontFamily, buttonLastEdit.Font.Size); pictureBoxLastEdit.Visible = true; pictureBoxLastEdit.Image = last.Image.GetBitmap(); buttonLastEdit.Text = string.Format(Configuration.Settings.Language.VobSubOcrCharacter.EditLastX, last.Text); pictureBoxLastEdit.Top = buttonLastEdit.Top - last.Image.Height + buttonLastEdit.Height; } else { buttonLastEdit.Visible = false; pictureBoxLastEdit.Visible = false; } 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; pictureBoxLastEdit.Left = buttonLastEdit.Left + buttonLastEdit.Width + 5; }
private CompareMatch GetCompareMatchNew(ImageSplitterItem targetItem, NikseBitmap parentBitmap, out CompareMatch secondBestGuess, List<ImageSplitterItem> list, int listIndex) { double maxDiff = (double)numericUpDownMaxErrorPct.Value; secondBestGuess = null; int index = 0; int smallestDifference = 10000; int smallestIndex = -1; NikseBitmap target = targetItem.NikseBitmap; if (_binaryOcrDb == null) { secondBestGuess = null; return null; } foreach (BinaryOcrBitmap compareItem in _binaryOcrDb.CompareImages) { // check for expand match! if (compareItem.ExpandCount > 0 && compareItem.Width > target.Width && parentBitmap.Width >= compareItem.Width + targetItem.X) // && parentBitmap.Height >= compareItem.Bitmap.Height + targetItem.Y) //NIXE-debug-test- what not correct? { int minY = targetItem.Y; for (int j = 1; j < compareItem.ExpandCount; j++) { if (list != null && list.Count > listIndex + j && list[listIndex + j].Y < minY) minY = list[listIndex + j].Y; } if (parentBitmap.Height >= compareItem.Height + minY) { var cutBitmap = parentBitmap.CopyRectangle(new Rectangle(targetItem.X, minY, compareItem.Width, compareItem.Height)); int dif = NikseBitmapImageSplitter.IsBitmapsAlike(compareItem, cutBitmap); 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 FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, target, _binaryOcrDb); if (maxDiff > 0) { if (smallestDifference * 100.0 / (target.Width * target.Height) > _vobSubOcrSettings.AllowDifferenceInPercent && target.Width < 70) { if (smallestDifference > 2 && target.Width > 25) { var cutBitmap = target.CopyRectangle(new Rectangle(4, 0, target.Width - 4, target.Height)); FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap, _binaryOcrDb); double differencePercentage = smallestDifference * 100.0 / (target.Width * target.Height); } if (smallestDifference > 2 && target.Width > 12) { var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height)); FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap, _binaryOcrDb); } if (smallestDifference > 2 && target.Width > 12) { var cutBitmap = target.CopyRectangle(new Rectangle(0, 0, target.Width - 2, target.Height)); FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap, _binaryOcrDb); } if (smallestDifference > 2 && target.Width > 12) { var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height)); int topCrop = 0; var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop, 2); if (cutBitmap2.Height != target.Height) FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2, _binaryOcrDb); } if (smallestDifference > 2 && target.Width > 15) { var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height)); int topCrop = 0; var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop); if (cutBitmap2.Height != target.Height) FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2, _binaryOcrDb); } if (smallestDifference > 2 && target.Width > 15) { var cutBitmap = target.CopyRectangle(new Rectangle(1, 0, target.Width - 2, target.Height)); int topCrop = 0; var cutBitmap2 = NikseBitmapImageSplitter.CropTopAndBottom(cutBitmap, out topCrop); if (cutBitmap2.Height != target.Height) FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, cutBitmap2, _binaryOcrDb); } } } if (smallestIndex >= 0) { double differencePercentage = smallestDifference * 100.0 / (target.Width * target.Height); if (differencePercentage <= maxDiff) { var hit = _binaryOcrDb.CompareImages[smallestIndex]; string text = hit.Text; int h = hit.Height; if (text == "V" || text == "W" || text == "U" || text == "S" || text == "Z" || text == "O" || text == "X" || text == "Ø" || text == "C") { if (_binOcrLastLowercaseHeight > 3 && h - _nocrLastLowercaseHeight < 2) text = text.ToLower(); } else if (text == "v" || text == "w" || text == "u" || text == "s" || text == "z" || text == "o" || text == "x" || text == "ø" || text == "c") { if (_binOcrLastUppercaseHeight > 3 && _binOcrLastUppercaseHeight - h < 2) text = text.ToUpper(); } hit.Text = text; if (smallestDifference < 0.1) SetBinOcrLowercaseUppercase(hit.Height, hit.Text); return new CompareMatch(hit.Text, hit.Italic, hit.ExpandCount, hit.Text + "_" + hit.Hash.ToString()); } var guess = _binaryOcrDb.CompareImages[smallestIndex]; secondBestGuess = new CompareMatch(guess.Text, guess.Italic, guess.ExpandCount, guess.Text + "_" + guess.Hash.ToString()); } return null; }
private static List<ImageSplitterItem> SplitHorizontal(ImageSplitterItem verticalItem, int xOrMorePixelsMakesSpace) { // split line into letters NikseBitmap bmp = verticalItem.NikseBitmap; var parts = new List<ImageSplitterItem>(); int size = 0; int startX = 0; int lastEndX = 0; int y = 0; bool spaceJustAdded = false; for (int x = 0; x < bmp.Width - 1; x++) { bool allTransparent = IsVerticalLineTransparent(bmp, ref y, x); // check if line is transparent and cursive bool cursiveOk = false; int tempY = 0; if (allTransparent == false && size > 5 && y > 3 && x < bmp.Width - 2 && !IsVerticalLineTransparent(bmp, ref tempY, x + 1)) { //Add space? if (lastEndX > 0 && lastEndX + xOrMorePixelsMakesSpace < startX) { int cleanCount = 0; for (int j = lastEndX; j < startX; j++) { int y1 = j; if (IsVerticalLineTransparentAlphaOnly(bmp, ref y1, j)) cleanCount++; } if (cleanCount > 0 && !spaceJustAdded) { parts.Add(new ImageSplitterItem(" ")); spaceJustAdded = true; } } var cursivePoints = new List<Point>(); cursiveOk = IsCursiveVerticalLineTransparent(bmp, size, y, x, cursivePoints); if (cursiveOk) { // make letter image int end = x + 1 - startX; if (startX > 0) { startX--; end++; } NikseBitmap b1 = bmp.CopyRectangle(new Rectangle(startX, 0, end, bmp.Height)); // b1.Save(@"d:\temp\cursive.bmp"); // just for debugging // make non-black/transparent stuff from other letter transparent foreach (Point p in cursivePoints) { for (int fixY = p.Y; fixY < bmp.Height; fixY++) b1.SetPixel(p.X - startX, fixY, Color.Transparent); } RemoveBlackBarRight(b1); // b1.Save(@"d:\temp\cursive-cleaned.bmp"); // just for debugging // crop and save image int addY; b1 = CropTopAndBottom(b1, out addY); parts.Add(new ImageSplitterItem(startX, verticalItem.Y + addY, b1)); spaceJustAdded = false; size = 0; startX = x + 1; lastEndX = x; } } if (!cursiveOk) { if (allTransparent) { if (size > 0) { if (size > 1) { //Add space? if (lastEndX > 0 && lastEndX + xOrMorePixelsMakesSpace < startX) { int cleanCount = 0; for (int j = lastEndX; j < startX; j++) { int y1 = j; if (IsVerticalLineTransparentAlphaOnly(bmp, ref y1, j)) cleanCount++; } if (cleanCount > 2 && !spaceJustAdded) { parts.Add(new ImageSplitterItem(" ")); spaceJustAdded = true; } } if (startX > 0) startX--; lastEndX = x; int end = x + 1 - startX; NikseBitmap part = bmp.CopyRectangle(new Rectangle(startX, 0, end, bmp.Height)); RemoveBlackBarRight(part); int addY; // part.Save("c:\\before" + startX.ToString() + ".bmp"); // just for debugging part = CropTopAndBottom(part, out addY); // part.Save("c:\\after" + startX.ToString() + ".bmp"); // just for debugging parts.Add(new ImageSplitterItem(startX, verticalItem.Y + addY, part)); spaceJustAdded = false; // part.Save(@"d:\temp\cursive.bmp"); // just for debugging } size = 0; } startX = x + 1; } else { size++; } } } if (size > 0) { if (lastEndX > 0 && lastEndX + xOrMorePixelsMakesSpace < startX && !spaceJustAdded) parts.Add(new ImageSplitterItem(" ")); if (startX > 0) startX--; lastEndX = bmp.Width - 1; int end = lastEndX + 1 - startX; NikseBitmap part = bmp.CopyRectangle(new Rectangle(startX, 0, end, bmp.Height - 1)); int addY; part = CropTopAndBottom(part, out addY); parts.Add(new ImageSplitterItem(startX, verticalItem.Y + addY, part)); //part.Save(@"d:\temp\cursive.bmp"); // just for debugging } return parts; }
private static IEnumerable<ImageSplitterItem> SplitHorizontalNew(ImageSplitterItem lineSplitterItem, int xOrMorePixelsMakesSpace) { var bmp = new NikseBitmap(lineSplitterItem.NikseBitmap); bmp.AddTransparentLineRight(); var parts = new List<ImageSplitterItem>(); int startX = 0; int width = 0; int spacePixels = 0; int subtractSpacePixels = 0; for (int x = 0; x < bmp.Width; x++) { bool right; bool clean; List<Point> points = IsVerticalLineTransparetNew(bmp, x, out right, out clean); if (points != null && clean) { spacePixels++; } if (right && points != null) { int add = FindMaxX(points, x) - x; width = width + add; subtractSpacePixels = add; } if (points == null) { width++; } else if (width > 1) { var bmp0 = new NikseBitmap(bmp); // remove pixels after current; int k = 0; foreach (Point p in points) { bmp0.MakeVerticalLinePartTransparent(p.X, p.X + k, p.Y); k++; } width = FindMaxX(points, x) - startX; width++; NikseBitmap b1 = bmp0.CopyRectangle(new Rectangle(startX, 0, width, bmp.Height)); if (spacePixels >= xOrMorePixelsMakesSpace && parts.Count > 0) parts.Add(new ImageSplitterItem(" ")); int addY; b1 = CropTopAndBottom(b1, out addY); parts.Add(new ImageSplitterItem(startX + lineSplitterItem.X, addY + lineSplitterItem.Y, b1)); //y is what? // remove pixels before next letter; int begin = 0; foreach (Point p in points) { bmp.MakeVerticalLinePartTransparent(begin, p.X, p.Y); } width = 1; startX = FindMinX(points, x); spacePixels = -subtractSpacePixels; subtractSpacePixels = 0; } else { width = 1; startX = FindMinX(points, x); } } return parts; }
private CompareMatch GetCompareMatchNew(ImageSplitterItem targetItem, NikseBitmap parentBitmap, out CompareMatch secondBestGuess, List<ImageSplitterItem> list, int listIndex) { double maxDiff = (double)numericUpDownMaxErrorPct.Value; secondBestGuess = null; int index = 0; int smallestDifference = 10000; int smallestIndex = -1; NikseBitmap target = targetItem.NikseBitmap; if (_binaryOcrDb == null) { secondBestGuess = null; return null; } var bob = new BinaryOcrBitmap(target); for (int k = 0; k < _binaryOcrDb.CompareImagesExpanded.Count; k++) { var b = _binaryOcrDb.CompareImagesExpanded[k]; if (bob.Hash == b.Hash && bob.Width == b.Width && bob.Height == b.Height && bob.NumberOfColoredPixels == b.NumberOfColoredPixels) { 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 { ok = false; break; } } if (ok) { secondBestGuess = null; return new CompareMatch(b.Text, b.Italic, b.ExpandCount, b.Key); } } } FindBestMatchNew(ref index, ref smallestDifference, ref smallestIndex, target, _binaryOcrDb, bob, maxDiff); if (smallestIndex >= 0) { double differencePercentage = smallestDifference * 100.0 / (target.Width * target.Height); if (differencePercentage <= maxDiff) { var hit = _binaryOcrDb.CompareImages[smallestIndex]; string text = hit.Text; if (smallestDifference > 0) { int h = hit.Height; if (text == "V" || text == "W" || text == "U" || text == "S" || text == "Z" || text == "O" || text == "X" || text == "Ø" || text == "C") { if (_binOcrLastLowercaseHeight > 3 && h - _binOcrLastLowercaseHeight < 2) text = text.ToLower(); } else if (text == "v" || text == "w" || text == "u" || text == "s" || text == "z" || text == "o" || text == "x" || text == "ø" || text == "c") { if (_binOcrLastUppercaseHeight > 3 && _binOcrLastUppercaseHeight - h < 2) text = text.ToUpper(); } } else { SetBinOcrLowercaseUppercase(hit.Height, text); } return new CompareMatch(text, hit.Italic, hit.ExpandCount, hit.Key); } var guess = _binaryOcrDb.CompareImages[smallestIndex]; secondBestGuess = new CompareMatch(guess.Text, guess.Italic, guess.ExpandCount, guess.Key); } return null; }