예제 #1
0
 public void SaveSoftMask(string input, string outputPath)
 {
     using (var rgbImage = Image.Load(input))
     {
         using (var output = new Image <Rgba32>(rgbImage.Width, rgbImage.Height))
         {
             var cache = new ImageCache(rgbImage);
             for (int x = 0; x < rgbImage.Width; x++)
             {
                 for (int y = 0; y < rgbImage.Height; y++)
                 {
                     output[x, y] = new Rgba32(cache[x, y], cache[x, y], cache[x, y]);
                 }
             }
             output.Save(outputPath);
         }
     }
 }
예제 #2
0
        internal static TargetMask FindCharacterMask(Point firstPixel, ImageCache image, CoordinateList blacklistedPoints, int minX, int maxX, int minY, int maxY)
        {
            var   points         = FindCharacterPixelPoints(firstPixel, image, blacklistedPoints, minX, maxX, minY, maxY);
            var   minPointX      = points.Min(p => p.X);
            var   mask           = new bool[points.Max(p => p.X) - points.Min(p => p.X) + 1, maxY - minY];
            var   softMask       = new float[points.Max(p => p.X) - points.Min(p => p.X) + 1, maxY - minY];
            var   pixelCount     = 0;
            float softPixelCount = 0;

            foreach (var p in points)
            {
                mask[p.X - minPointX, p.Y - minY]     = true;
                softMask[p.X - minPointX, p.Y - minY] = image[p.X, p.Y];
                softPixelCount += image[p.X, p.Y];
                pixelCount++;
            }
            return(new TargetMask(mask, points.Max(p => p.X), minPointX, points.Max(p => p.X) - minPointX + 1, pixelCount, softPixelCount, softMask));
        }
예제 #3
0
        internal static List <Point> FindCharacterPixelPoints(Point firstPixel, ImageCache image, CoordinateList blacklistedPoints, int minX, int maxX, int minY, int maxY)
        {
            var characterPoints = new CoordinateList();

            AddConnectedPoints(characterPoints, firstPixel, image, blacklistedPoints, minX, maxX, minY, maxY);

            var midX = (int)characterPoints.Average(p => p.X);

            //Scan down from the initial midpoint for gap characters
            //Account for gaps such as in i or j
            for (int y = characterPoints.Where(p => p.X == midX).Max(p => p.Y) + 1; y < maxY; y++)
            {
                AddConnectedPoints(characterPoints, new Point(midX, y), image, blacklistedPoints, minX, maxX, minY, maxY);
            }
            //Scan up from new midpoint for gap characters that have a bit sticking out the front. Account for gaps like in ;
            midX = (int)characterPoints.Average(p => p.X);
            var highestY = characterPoints.Min(p => p.X == midX ? p.Y : maxY);

            for (int i = highestY; i >= minY; i--)
            {
                AddConnectedPoints(characterPoints, new Point(midX, i), image, blacklistedPoints, minX, maxX, minY, maxY);
            }
            //Account for crazy gaps such as in %
            var foundNewPixels = false;

            do
            {
                foundNewPixels = false;
                var maxCharX = characterPoints.Max(p => p.X);
                for (int y = characterPoints.Where(p => p.X == maxCharX).Min(p => p.Y) + 1; y < minY + ((maxY - minY) * 0.75f); y++)
                {
                    var origCount = characterPoints.Count;
                    AddConnectedPoints(characterPoints, new Point(maxCharX, y), image, blacklistedPoints, minX, maxX, minY, maxY);
                    if (characterPoints.Count > origCount)
                    {
                        foundNewPixels = true;
                    }
                }
            } while (foundNewPixels);

            return(new List <Point>(characterPoints));
        }
예제 #4
0
        private static void AddConnectedPoints(CoordinateList existingPoints, Point firstPixel, ImageCache image, CoordinateList blacklistedPoints, int minX, int maxX, int minY, int maxY)
        {
            if (image[firstPixel.X, firstPixel.Y] <= 0 && firstPixel.X >= minX && firstPixel.X < maxX && firstPixel.Y >= minY && firstPixel.Y < maxY)
            {
                return;
            }
            var q = new Queue <Point>();

            if (!existingPoints.Exists(firstPixel))
            {
                existingPoints.Add(firstPixel);
                q.Enqueue(firstPixel);
            }
            while (q.Count > 0)
            {
                var n = q.Dequeue();
                if (n.X + 1 <= maxX &&
                    image[n.X + 1, n.Y] > 0 &&
                    !existingPoints.Exists(n.X + 1, n.Y) &&
                    (blacklistedPoints == null || !blacklistedPoints.Exists(n.X + 1, n.Y)))
                {
                    var np = new Point(n.X + 1, n.Y);
                    existingPoints.Add(np);
                    q.Enqueue(np);
                }
                if (n.X - 1 >= minX &&
                    image[n.X - 1, n.Y] > 0 &&
                    !existingPoints.Exists(n.X - 1, n.Y) &&
                    (blacklistedPoints == null || !blacklistedPoints.Exists(n.X - 1, n.Y)))
                {
                    var np = new Point(n.X - 1, n.Y);
                    existingPoints.Add(np);
                    q.Enqueue(np);
                }
                if (n.Y - 1 >= minY &&
                    image[n.X, n.Y - 1] > 0 &&
                    !existingPoints.Exists(n.X, n.Y - 1) &&
                    (blacklistedPoints == null || !blacklistedPoints.Exists(n.X, n.Y - 1)))
                {
                    var np = new Point(n.X, n.Y - 1);
                    existingPoints.Add(np);
                    q.Enqueue(np);
                }
                if (n.Y + 1 < maxY &&
                    image[n.X, n.Y + 1] > 0 &&
                    !existingPoints.Exists(n.X, n.Y + 1) &&
                    (blacklistedPoints == null || !blacklistedPoints.Exists(n.X, n.Y + 1)))
                {
                    var np = new Point(n.X, n.Y + 1);
                    existingPoints.Add(np);
                    q.Enqueue(np);
                }
            }
        }
예제 #5
0
        private List <TrainingSampleCharacter> TrainOnLine(char[] referenceCharacters, int xOffset, Rectangle chatRect, ImageCache image, int lineHeight, int lineOffset)
        {
            var          startX = xOffset;
            var          endX   = xOffset;
            List <Point> targetCharacterPixels = null;
            var          refIndex = 0;
            var          results  = new List <TrainingSampleCharacter>();

            for (int x = xOffset; x < chatRect.Right; x++)
            {
                //Advance until next pixel
                var firstPixel = Point.Empty;
                for (int i = endX; i < chatRect.Right; i++)
                {
                    var pixelFound = false;
                    for (int y = lineOffset; y < lineOffset + lineHeight; y++)
                    {
                        if (image[i, y] > 0.3f)
                        {
                            x          = i;
                            pixelFound = true;
                            firstPixel = new Point(i, y);
                            break;
                        }
                    }

                    if (pixelFound)
                    {
                        break;
                    }
                }

                //Make sure we didn't escape
                if (x >= chatRect.Right || firstPixel == Point.Empty)
                {
                    break;
                }

                startX = chatRect.Right;
                //targetCharacterPixels = OCRHelpers.FindCharacterPixelPoints(firstPixel, image, null, chatRect.Left, chatRect.Right, lineOffset, lineOffset + lineHeight);
                //var minX = targetCharacterPixels.Min(p => p.X);
                //var minY = targetCharacterPixels.Min(p => p.Y);
                //using (var image2 = new Image<Rgba32>(targetCharacterPixels.Max(p => p.X) - targetCharacterPixels.Min(p => p.X) + 1, targetCharacterPixels.Max(p => p.Y) - targetCharacterPixels.Min(p => p.Y) + 1))
                //{
                //    for (int x2 = 0; x2 < image2.Width; x2++)
                //    {
                //        for (int y2 = 0; y2 < image2.Height; y2++)
                //        {
                //            var p = targetCharacterPixels.FirstOrDefault(p2 => p2.X == x2 + minX  && p2.Y == y2 + minY);
                //            if (p != null)
                //                image2[x2, y2] = new Rgba32(image[p.X, p.Y], image[p.X, p.Y], image[p.X, p.Y]);
                //            else
                //                image2[x2, y2] = Rgba32.Black;
                //        }
                //    }
                //    image2.Save("debug_target.png");
                //}
                var target = OCRHelpers.FindCharacterMask(firstPixel, image, null, chatRect.Left, chatRect.Right, lineOffset, lineOffset + lineHeight);
                var mask   = new float[target.Width, lineHeight];
                for (int x2 = 0; x2 < target.Width; x2++)
                {
                    for (int y2 = 0; y2 < lineHeight; y2++)
                    {
                        mask[x2, y2] = Math.Max(0, image[target.MinX + x2, y2 + lineOffset]);
                    }
                }

                startX = Math.Min(startX, target.MinX);
                endX   = Math.Max(endX, target.MaxX + 1);

                results.Add(new TrainingSampleCharacter()
                {
                    Mask = mask, Width = endX - startX, Character = referenceCharacters[refIndex++]
                });
                x = endX;
            }
            if (referenceCharacters.Length > refIndex)
            {
                throw new Exception("Length missmatch on training line");
            }

            return(results);
        }