Пример #1
0
        /// <summary>
        /// Metodo que obtiene las subimagenes a partir de los huecos.
        /// </summary>
        /// <param name="image">La imagen a segmentar.</param>
        /// <param name="holes">
        /// Los huecos considerados para separar las partes de la imagen.
        /// </param>
        /// <returns>Un array con las subimagenes obtenidas al segmentar.</returns>
        private List <MathTextBitmap> ImageCut(MathTextBitmap image,
                                               List <Hole> holes)
        {
            List <MathTextBitmap> newBitmaps = new List <MathTextBitmap>();

            int start, size;
            int xpos = image.Position.X;
            int ypos = image.Position.Y;

            for (int i = 0; i < holes.Count - 1; i++)
            {
                //El texto esta entre el final de un hueco, y el inicio del siguiente;
                start = ((Hole)holes[i]).EndPixel;
                size  = ((Hole)holes[i + 1]).StartPixel - start + 1;

                int x0, y0;
                int width0, height0;
                if (mode == ProjectionMode.Horizontal)
                {
                    x0      = start;
                    y0      = 0;
                    width0  = size;
                    height0 = image.Height;
                }
                else
                {
                    x0      = 0;
                    y0      = start;
                    width0  = image.Width;
                    height0 = size;
                }

                // Recortamos
                FloatBitmap cutImage =
                    image.FloatImage.SubImage(x0, y0, width0, height0);

                // Encuadramos
                Gdk.Point pd;
                Gdk.Size  sd;
                GetEdges(cutImage, out pd, out sd);
                cutImage = cutImage.SubImage(pd.X, pd.Y, sd.Width, sd.Height);
                // Montamos el bitmap
                MathTextBitmap newBitmap =
                    new MathTextBitmap(cutImage,
                                       new Point(xpos + x0 + pd.X,
                                                 ypos + y0 + pd.Y));

                newBitmaps.Add(newBitmap);
            }

            if (newBitmaps.Count == 1)
            {
                newBitmaps.Clear();
            }


            return(newBitmaps);
        }
        private List <MathTextBitmap> WaterfallSegment(MathTextBitmap bitmap)
        {
            FloatBitmap image = Rotate(bitmap.FloatImage);

            if (reflection)
            {
                image = Reflect(image);
            }


            // Buscamos un pixel blanco en el que empezar.

            List <Point> points = new List <Point>();

            // Aqui vamos a pintar la linea que divide las dos partes de la imagen.
            FloatBitmap cutImage = new FloatBitmap(image.Width, image.Height);

            // Buscamos por filas, desde abajo, para encontrar el primer pixel
            // negro mas cercano a la esquina (0,0).
            int i, j, k;

            if (search)

            {
                bool startFound = false;
                for (j = 0; j < image.Height && !startFound; j++)
                {
                    for (i = 0; i < image.Width && !startFound; i++)
                    {
                        if (image[i, j] != FloatBitmap.White)
                        {
                            for (k = 0; k < j; k++)
                            {
                                // Añadimos a la lista de puntos los puntos
                                // entre el borde inferior y el punto en la fila
                                // inmediatamente inferior a la del punto negro.

                                points.Add(new Point(i, k));
                                cutImage[i, k] = FloatBitmap.Black;
                            }
                            startFound = true;
                        }
                    }
                }
            }
            else
            {
                points.Add(new Point(image.Width / 2, 0));
                cutImage[image.Width / 2, 0] = FloatBitmap.Black;
            }


            if (points.Count == 0)
            {
                return(new List <MathTextBitmap>());
            }

            int x = points[0].X;
            int y = points[0].Y;

            bool newPoints   = true;
            bool borderFound = false;

            while (newPoints && !borderFound)
            {
                if (x == image.Width - 1 ||
                    y == image.Height - 1)
                {
                    borderFound = true;
                }
                else
                {
                    // Aqui almacenamos los posibles vectores..
                    int [] vectors = new int[] { 0, 1, 1, 1, 1, 0, -1, 0, -1, 1, -1, -1, 0, -1 };

                    bool notNewFound = true;
                    for (k = 0; k < vectors.Length && notNewFound; k += 2)
                    {
                        int xd = vectors[k];
                        int yd = vectors[k + 1];
                        // Vamos comprobando los casos
                        // Tenemos que:
                        // · No salirnos de los limites
                        // · El pixel ha de ser blanco.
                        // . No puede ser el anterior del actual, para no meternos
                        //   en un bucle.
                        if (x + xd >= 0 &&
                            y + yd >= 0 &&
                            x + xd < image.Width &&
                            y + yd < image.Height &&
                            image[x + xd, y + yd] == FloatBitmap.White &&
                            !points.Contains(new Point(x + xd, y + yd)))

                        {
                            x = x + xd;
                            y = y + yd;
                            points.Add(new Point(x, y));
                            cutImage[x, y] = FloatBitmap.Black;

                            // Indicamos que hemos encontrado el valor.
                            notNewFound = false;
                        }
                    }

                    newPoints = !notNewFound;
                }
            }

            List <MathTextBitmap> children = new List <MathTextBitmap>();

            // Hemos encontrado el borde, cortamos la imagen.
            if (borderFound)
            {
                // Primero encontramos un punto blanco.
                bool whiteFound = false;
                int  x0 = 0, y0 = 0;
                for (i = 0; i < cutImage.Width && !whiteFound; i++)
                {
                    for (j = 0; j < cutImage.Height && !whiteFound; j++)
                    {
                        if (cutImage[i, j] != FloatBitmap.Black)
                        {
                            // Mas que el primer blaco, buscamos el primer
                            // negro;
                            whiteFound = true;
                            x0         = i;
                            y0         = j;
                        }
                    }
                }

                if (reflection)
                {
                    cutImage = Reflect(cutImage);
                }

                // Tenemos que rotar la imagen de corte para alinearla con la orginal.
                cutImage = UndoRotate(cutImage);


                // Rellenamos la imagen de negro a partir del punto encontrado.
                cutImage.Fill(x0, y0, FloatBitmap.Black);

#if DEBUG
                string path = System.IO.Path.GetTempFileName();
                cutImage.CreatePixbuf().Save(String.Format(path + "_{0}_{1}.png", mode, reflection), "png");
#endif

                // Recorremos la imagen de corte, y sacamos dos imagenes;
                FloatBitmap res1 = new FloatBitmap(cutImage.Width, cutImage.Height);
                FloatBitmap res2 = new FloatBitmap(cutImage.Width, cutImage.Height);



                FloatBitmap origImage    = bitmap.FloatImage;
                bool        res1HasBlack = false;
                bool        res2HasBlack = false;

                for (i = 0; i < cutImage.Width; i++)
                {
                    for (j = 0; j < cutImage.Height; j++)
                    {
                        // Si estamos en la zona negra de la imagen de corte,
                        // copiamos en la primera imagen de resultado,
                        // y sino, en la segunda.
                        if (cutImage[i, j] == FloatBitmap.Black)
                        {
                            res1[i, j] = origImage[i, j];
                            if (origImage[i, j] != FloatBitmap.White)
                            {
                                res1HasBlack = true;
                            }
                        }
                        else
                        {
                            res2[i, j] = origImage[i, j];
                            if (origImage[i, j] != FloatBitmap.White)
                            {
                                res2HasBlack = true;
                            }
                        }
                    }
                }



                // Si las dos imágenes tienen pixeles negros, hemos separado la
                // imagen correctamente, sino, solo hemos rodeado algo
                // que no fuimos capaces de segmentar.
                // Si no, no segmenatamos nada, se devolverá la lista vacia.
                if (res1HasBlack && res2HasBlack)
                {
                    Gdk.Point pd;
                    Gdk.Size  sd;
                    GetEdges(res1, out pd, out sd);
                    res1 = res1.SubImage(pd.X, pd.Y, sd.Width, sd.Height);
                    children.Add(new MathTextBitmap(res1,
                                                    new Gdk.Point(bitmap.Position.X + pd.X,
                                                                  bitmap.Position.Y + pd.Y)));

                    GetEdges(res2, out pd, out sd);
                    res2 = res2.SubImage(pd.X, pd.Y, sd.Width, sd.Height);
                    children.Add(new MathTextBitmap(res2,
                                                    new Gdk.Point(bitmap.Position.X + pd.X,
                                                                  bitmap.Position.Y + pd.Y)));
                }
            }

            return(children);
        }