/// <summary>
		/// Se aplica el algoritmo de binarización de umbral fijo.
		/// </summary>
		/// <param name = "image">
		/// La imagen que se binarizará.
		/// </param>
		/// <returns>
		/// La imagen binarizada.
		/// </returns>		
		public override FloatBitmap Apply(FloatBitmap image)
		{
			int nrows=image.Width;
			int ncols=image.Height;
			
			FloatBitmap res = new FloatBitmap(nrows, ncols);
			
			float fthreshold = threshold / 255f;

			for (int i=0; i<nrows; i++)
			{
				for (int j=0; j<ncols; j++)
				{
					if (image[i,j] < fthreshold)
					{
						res[i,j] = FloatBitmap.Black;
					}
					else
					{
						res[i,j] = FloatBitmap.White;
					}
				}
			}
			
			return res;
		}
		/// <summary>
		/// Creamos una nueva imagen con dos filas y columnas mas, necesesario para el algoritmo.
		/// </summary>
		/// <param name="image">La imagen a procesar.</param>
		/// <returns>La imagen con las filas y columnas añadidas.</returns>
		private FloatBitmap CreateAuxImage(FloatBitmap image)
		{
			// La nueva imagen tiene dos filas y dos columnas mas que la original
			FloatBitmap newImage=new FloatBitmap(width,height);

			float brightness;
			for(int i = 0; i < width - 2; i++)
			{
				for(int j = 0; j < height - 2; j++)
				{
										
					brightness = image[i, j];
					
					newImage[i + 1,j + 1] = brightness;
				}
			}
			
			for(int i=0;i< width;i++) 
			{
				newImage[i,0]=1;
				newImage[i,height-1]=1;
			}
			for(int j=0;j< height;j++)
			{
				newImage[0,j]=1;
				newImage[width-1,j]=1;
			}
			return newImage;
		}
		public static int BlackNeighbours(FloatBitmap image,
		                                  int x, int y)
		{
			int res=0;
			int width = image.Width;
			int height = image.Height;
			
			if(x-1>=0 && y-1 >= 0 && image[x-1,y-1]!=FloatBitmap.White)
				res++;
			if(x-1>=0 && image[x-1,y]!=FloatBitmap.White)
				res++;
			if(x-1>=0 && y+1 < height && image[x-1,y+1]!=FloatBitmap.White)
				res++;			
			if(y-1 >= 0 && image[x,y-1]!=FloatBitmap.White)
				res++;
			if(y+1 < height && image[x,y+1]!=FloatBitmap.White)
				res++;			
			if(x+1 < width && y-1 >= 0 && image[x+1,y-1]!=FloatBitmap.White)
				res++;
			if(x+1 < width && image[x+1,y]!=FloatBitmap.White)
				res++;
			if(x+1 < width && y+1 < height && image[x+1,y+1]!=FloatBitmap.White)
				res++;
			return res;
			
		}
		/// <summary>
		/// Este es el metodo a invocar para realizar el
		/// adelgazamiento de la imagen.
		/// </summary>
		/// <param name="image">
		/// La imagen a ser procesada.
		/// </param>
		public override FloatBitmap Apply(FloatBitmap image)
		{
			width=image.Width+2;
			height=image.Height+2;

			FloatBitmap newImage=CreateAuxImage(image);

			/* Pre_process */
			PreSmooth(newImage);
			Aae(newImage);
			
			ZhangSuenStentifordHoltThinning(newImage);

			FloatBitmap res = new FloatBitmap(width - 2 , height -2);

			
			for(int i=0;i<width-2; i++)
			{
				for(int j=0;j<height-2; j++)
				{
					res[i,j] = newImage[i + 1,j + 1];
				}
			}
			
			return res;
		}
		/// <summary>
		/// Crea una nueva imagen añadiendo columnas en blanco a izquierda y derecha.
		/// </summary>
		/// <param name="image">La imagen a la que vamos a añadir columnas.</param>
		/// <param name="pad">El ancho del relleno a añadir.</param>
		/// <param name="y1">La coordenada Y de la esquina superior izquierda del contenido.</param>
		/// <param name="x1">La coordenada X de la esquina superior izquierda del contenido.</param>
		/// <param name="height">La altura del contenido.</param>
		/// <param name="width">La anchura del contenido.</param>
		/// <returns> 
		/// Una matriz bidimensional con la imagen con las columnas añadidas.
		/// </returns>
		private FloatBitmap CreateNewImageColumns(FloatBitmap image, int pad, int y1,
		                                          int x1, int height, int width)
		{
			// La nueva altura es la antigua mas dos, porque añdimos una
			// filas en blanco como borde
			// la nueva anchura es igual a la altura
			int newWidth=height+2;
			int newHeight=height+2;			
			
			FloatBitmap newImage = new FloatBitmap(newWidth,newHeight);
			
			for(int i=0;i<newWidth;i++)
			{
				for(int j=0;j<newHeight;j++)
				{
					newImage[i,j]= FloatBitmap.White;
				}
			}
			
			// Copiamos la imagen original centrada
			for(int i=0;i<width;i++)
			{
				for(int j=0;j<height;j++)
				{
					int centerH=i+(int)Math.Ceiling(((double)pad)/2.0)+1;
					newImage[centerH,j+1]=image[i+x1,j+y1];
				}
			}	
			
			return newImage;
		}
		/// <summary>
		/// Obtiene el menor rectangulo que contiene los pixeles negros de
		/// la imagen y devuelve sus esquinas superior izquierda e
		/// inferior derecha como (x1,y1) y (x2,y2) respectivamente.
		/// </summary>
		/// <param name="image">Imagen sobre la que se trabaja</param>
		/// <param name="x1">Minima coordenada horizontal</param>
		/// <param name="y1">Minima coordenada vertical</param>
		/// <param name="x2">Maxima coordenada horizontal</param>
		/// <param name="y2">Maxima coordenada vertical</param>
		public static void BoxImage(FloatBitmap image, out int x1, out int y1, out int x2, out int y2)
		{
			x1 = FindLeft(image);
			y1 = FindTop(image);
			x2 = FindRight(image);
			y2 = FindBottom(image);
		}
		/// <summary>
		/// Cuenta el numero de pixeles negros en la mitad indicada por <c>h</c>.
		/// </summary>
		/// <remarks>
		/// Si la imagen tiene un numero impar de pixeles se incluye la fila
		/// o columna central, segun el caso.
		/// </remarks>
		/// <param name="image">Imagen sobre la que se trabaja</param>
		/// <param name="h">Mitad a analizar</param>
		/// <returns>Numero de pixeles negros</returns>
		public static int NumBlackPixelsInHalf(FloatBitmap image, Half h)
		{
			int n=0;
			
			int width = image.Width;
			int height = image.Height;
			int halfWidth = width/2;
			int halfHeight = height/2;
			
			switch(h) 
			{
				case(Half.Top):
					n=NumPixelsInArea(image,FloatBitmap.Black,
					                  0,0,
					                  width,halfHeight);
					break;
				case(Half.Bottom):
					n=NumPixelsInArea(image,FloatBitmap.Black,
					                  0,halfHeight,
					                  width,height);
					break;
				case(Half.Left):
					n=NumPixelsInArea(image,FloatBitmap.Black,
					                  0,0,
					                  halfWidth,height);
					break;
				case(Half.Right):
					n=NumPixelsInArea(image,FloatBitmap.Black,
					                  halfWidth,0,
					                  width,height);
					break;
			}
			
			return n;			
		}
		/// <summary>
		/// Este metodo efectua el escalado de la imagen.
		/// </summary>
		/// <param name="image">La imagen que queremos escalar.</param>
		/// <returns>La imagen escalada al tamaño establecido.</returns>
		public override FloatBitmap Apply(FloatBitmap image) 
		{
			Pixbuf pb = image.CreatePixbuf();
				
			pb = pb.ScaleSimple(normalizedSize, normalizedSize, InterpType.Bilinear);
			
			return FloatBitmap.CreateFromPixbuf(pb);
		}
		/// <summary>
		/// Enmarca una imagen.
		/// </summary>
		/// <param name="image">
		/// La imagen a enmarcar.
		/// </param>
		/// <param name="pos">
		/// La esquina de la zona a recortar.
		/// </param>
		/// <param name="size">
		/// El tamaño de la zona a recortar.
		/// </param>
		protected void GetEdges(FloatBitmap image, out Point pos, out Size size)
		{
			pos = new Point(0,0);
			size = new Size(image.Width, image.Height);
			
			bool found =false;
			
			for(int i = 0; i < image.Width && !found; i++)
			{
				for(int j = 0; j < image.Height && !found; j++)
				{
					if (image[i, j] != FloatBitmap.White)
					{
						pos.X = i-1;
						found = true;
					}
				}
			}
			
			found =false;
			for(int i = image.Width-1; i >=0 && !found; i--)
			{
				for(int j = 0; j < image.Height && !found; j++)
				{
					if (image[i, j] != FloatBitmap.White)
					{
						size.Width = i - pos.X +2 ;
						found = true;
					}
				}
			}
			
			found =false;
			for(int j = 0; j < image.Height && !found; j++)
			{
				for(int i = 0; i < image.Width&& !found; i++)
				{
					if (image[i, j] != FloatBitmap.White)
					{
						pos.Y = j-1;
						found = true;
					}
				}
			}
			
			found =false;
			for(int j = image.Height-1; j >=0 && !found; j--)
			{
				for(int i = 0; i < image.Width && !found; i++)
				{
					if (image[i, j] != FloatBitmap.White)
					{
						size.Height = j - pos.Y +2;
						found = true;
					}
				}
			}
		}
		public override bool Apply(FloatBitmap image)
		{
			int npixelsLeft=CountPixelsHelper.NumBlackPixelsInHalf(image, Half.Left);
			int npixelsRight=CountPixelsHelper.NumBlackPixelsInHalf(image, Half.Right);
			
			int tolerance = (int)((image.Width * image.Height)*epsilon);
			
			return npixelsLeft > npixelsRight + tolerance;
		}
		public override bool Apply(FloatBitmap image)
		{
			int npixelsTop=CountPixelsHelper.NumBlackPixelsInHalf(image, Half.Top);
			int npixelsBottom=CountPixelsHelper.NumBlackPixelsInHalf(image, Half.Bottom);

			int tolerance = (int)((image.Width * image.Height)*epsilon);
			
			return npixelsTop > npixelsBottom + tolerance;
		}
		/// <summary>
		/// Constructor de un nuevo <c>MathTextBitmap</c> a partir de un
		/// array de float y su posicion y un modo de proyeccion.
		/// </summary>
		/// <remarks>
		/// El array se clona para evitar efectos laterales. La imagen se
		/// procesa mediante el metodo <c>ProcessImage()</c>. 
		/// </remarks>
		public MathTextBitmap(FloatBitmap image, Point pos)
		{
			this.image =  image;
			this.position = pos;
			
			processedImages = new List<FloatBitmap>();
			
			width = image.Width;
			height = image.Height;
		}
		/// <summary>
		/// Constructor de un nuevo <c>MathTextBitmap</c> a partir de un
		/// <c>Bitmap</c>.
		/// </summary>
		/// <remarks>
		/// El bitmap se convierte a escala de grises y se procesa mediante
		/// el metodo <c>ProcessImage()</c>.
		/// </remarks>
		/// <seealso cref="System.Drawing.Bitmap"/>
		public MathTextBitmap(Pixbuf b)
		{
			this.position = new Point(0,0);
			
			processedImages = new List<FloatBitmap>();
			
			image = FloatBitmap.CreateFromPixbuf(b);	
			width = b.Width;
			height = b.Height;
		}	
示例#14
0
        /// <summary>
        /// Constructor de un nuevo <c>MathTextBitmap</c> a partir de un
        /// <c>Bitmap</c>.
        /// </summary>
        /// <remarks>
        /// El bitmap se convierte a escala de grises y se procesa mediante
        /// el metodo <c>ProcessImage()</c>.
        /// </remarks>
        /// <seealso cref="System.Drawing.Bitmap"/>
        public MathTextBitmap(Pixbuf b)
        {
            this.position = new Point(0, 0);

            processedImages = new List <FloatBitmap>();

            image  = FloatBitmap.CreateFromPixbuf(b);
            width  = b.Width;
            height = b.Height;
        }
示例#15
0
        /// <summary>
        /// Constructor de un nuevo <c>MathTextBitmap</c> a partir de un
        /// array de float y su posicion y un modo de proyeccion.
        /// </summary>
        /// <remarks>
        /// El array se clona para evitar efectos laterales. La imagen se
        /// procesa mediante el metodo <c>ProcessImage()</c>.
        /// </remarks>
        public MathTextBitmap(FloatBitmap image, Point pos)
        {
            this.image    = image;
            this.position = pos;

            processedImages = new List <FloatBitmap>();

            width  = image.Width;
            height = image.Height;
        }
		public void CountPixelsHelperHalfsTest()
		{
			
			FloatBitmap bitmap = new FloatBitmap(5,5);	
			bitmap[1,0] = FloatBitmap.Black;
			bitmap[1,1] = FloatBitmap.Black;
			bitmap[3,2] = FloatBitmap.Black;
			
			int ct1 = CountPixelsHelper.NumBlackPixelsInHalf(bitmap, Half.Top);
			int cb1 = CountPixelsHelper.NumBlackPixelsInHalf(bitmap, Half.Bottom);
			int cl1 = CountPixelsHelper.NumBlackPixelsInHalf(bitmap, Half.Left);
			int cr1 = CountPixelsHelper.NumBlackPixelsInHalf(bitmap, Half.Right);
			
			Assert.AreEqual(2, ct1,"Arriba 1");
			Assert.AreEqual(1, cb1,"Abajo 1");
			Assert.AreEqual(2, cl1,"Izquierda 1");
			Assert.AreEqual(1, cr1,"Derecha 1");
			
			bitmap = bitmap.Rotate90();
			
			int ct2 = CountPixelsHelper.NumBlackPixelsInHalf(bitmap, Half.Top);
			int cb2 = CountPixelsHelper.NumBlackPixelsInHalf(bitmap, Half.Bottom);
			int cl2 = CountPixelsHelper.NumBlackPixelsInHalf(bitmap, Half.Left);
			int cr2 = CountPixelsHelper.NumBlackPixelsInHalf(bitmap, Half.Right);
			
			Assert.AreEqual(1, ct2,"Arriba 2");
			Assert.AreEqual(2, cb2,"Abajo 2");
			Assert.AreEqual(2, cl2,"Izquierda 2 ");
			Assert.AreEqual(1, cr2,"Derecha 2");
			
			bitmap = bitmap.Rotate90();
			
			int ct3 = CountPixelsHelper.NumBlackPixelsInHalf(bitmap, Half.Top);
			int cb3 = CountPixelsHelper.NumBlackPixelsInHalf(bitmap, Half.Bottom);
			int cl3 = CountPixelsHelper.NumBlackPixelsInHalf(bitmap, Half.Left);
			int cr3 = CountPixelsHelper.NumBlackPixelsInHalf(bitmap, Half.Right);
			
			Assert.AreEqual(0, ct3,"Arriba 3");
			Assert.AreEqual(3, cb3,"Abajo 3");
			Assert.AreEqual(1, cl3,"Izquierda 3");
			Assert.AreEqual(2, cr3,"Derecha 3");
			
			bitmap = bitmap.Rotate90();
			
			int ct4 = CountPixelsHelper.NumBlackPixelsInHalf(bitmap, Half.Top);
			int cb4 = CountPixelsHelper.NumBlackPixelsInHalf(bitmap, Half.Bottom);
			int cl4 = CountPixelsHelper.NumBlackPixelsInHalf(bitmap, Half.Left);
			int cr4 = CountPixelsHelper.NumBlackPixelsInHalf(bitmap, Half.Right);
			
			Assert.AreEqual(2, ct4,"Arriba 4");
			Assert.AreEqual(1, cb4,"Abajo 4");
			Assert.AreEqual(0, cl4,"Izquierda 4");
			Assert.AreEqual(3, cr4,"Derecha 4");
		}
示例#17
0
 /// <summary>
 /// Constructor copia de <c>FloatBitmap</c>.
 /// </summary>
 /// <param name="source">
 /// La instancia que se copiará.
 /// </param>
 public FloatBitmap(FloatBitmap source)
     : this(source.Width, source.Height)
 {
     for (int i = 0; i < source.Width; i++)
     {
         for (int j = 0; j < source.Height; j++)
         {
             this.image[i, j] = source.image[i, j];
         }
     }
 }
示例#18
0
		public void FloatImageRotationTest()
		{
			FloatBitmap bitmap = new FloatBitmap(5, 4);
			
			bitmap[3,1] = FloatBitmap.White;
			
			FloatBitmap rotatedBitmap = bitmap.Rotate90();
			Assert.AreEqual(FloatBitmap.White, rotatedBitmap[1,2]);
			
			
		}
		public override bool Apply(FloatBitmap image)
		{
			if(CountColorChangesHelper.NumColorChangesColumn(image, 
			                                                 image.Height/2) < 2) 
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		public override bool Apply(FloatBitmap image)
		{
			if(CountColorChangesHelper.NumColorChangesRow(image,
			                                              image.Width/2) > 4) 
			{
				return true;
			}
			else
			{
				return false;
			}
		}
示例#21
0
        /// <summary>
        /// Procesa la imagen actual mediante binarizacion, encuadre,
        /// normalizacion y adelgazamiento.
        /// </summary>
        public void ProcessImage(List <BitmapProcess> processes)
        {
            FloatBitmap processedImage = new FloatBitmap(image);

            foreach (BitmapProcess process in processes)
            {
                processedImage = process.Apply(processedImage);
            }


            processedImages.Add(processedImage);
        }
示例#22
0
		/// <summary>
		/// Constructor copia de <c>FloatBitmap</c>.
		/// </summary>
		/// <param name="source">
		/// La instancia que se copiará.
		/// </param>
		public FloatBitmap(FloatBitmap source)
			: this(source.Width, source.Height)
		{
			for(int i=0; i<source.Width; i++)
			{
				for(int j=0;j<source.Height; j++)
				{
					this.image[i,j] = source.image[i,j];
				}
				
			}
		}
		public override bool Apply(FloatBitmap image)
		{
			int npixelsNW=CountPixelsHelper.NumBlackPixelsInQuadrant(image, Quadrant.NW);
			int npixelsNE=CountPixelsHelper.NumBlackPixelsInQuadrant(image, Quadrant.NE);
			int npixelsSW=CountPixelsHelper.NumBlackPixelsInQuadrant(image, Quadrant.SW);
			int npixelsSE=CountPixelsHelper.NumBlackPixelsInQuadrant(image, Quadrant.SE);

			int tolerance = (int)((image.Width * image.Height)*epsilon);
			
			return (npixelsSE>npixelsNE + tolerance) 
				&& (npixelsSE>npixelsNW + tolerance)
				&& (npixelsSE>npixelsSW + tolerance);
		}
		public override bool Apply (FloatBitmap image)
		{
			MathTextBitmap bitmap = new MathTextBitmap(image, new Gdk.Point(0,0));
			foreach (BitmapSegmenter segmenter in segmenters) 
			{
				if(segmenter.Segment(bitmap).Count>1)
				{
					return true;
				}
			}
			
			return false;
		}
示例#25
0
        /// <summary>
        /// Devuelve una sub imagene.
        /// </summary>
        /// <param name="x">Minima posicion horizontal de la subimagen.</param>
        /// <param name="y">Minima posicion vertical de la subimagen.</param>
        /// <param name="width">Anchura de la subimagen medida desde <c>x</c></param>
        /// <param name="height">Altura de la subimagen medida desde <c>y</c></param>
        /// <returns>Array de float que representa la subimagen deseada.</returns>
        public FloatBitmap SubImage(int x, int y, int width, int height)
        {
            FloatBitmap resImage = new FloatBitmap(width, height);

            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    resImage[i, j] = this[x + i, y + j];
                }
            }

            return(resImage);
        }
		/// <summary>
		/// Cuenta el numero de pixeles negros en una imagen en la
		/// fila indicada.
		/// </summary>
		/// <param name="image">Imagen sobre la que se trabaja</param>
		/// <param name="row">Fila a analizar</param>
		/// <returns>Numero de pixeles negros</returns>
		public static int NumBlackPixelsRow(FloatBitmap image, int row) 
		{
			int nBlackPixels=0;

			for(int i=0; i<image.Width; i++) 
			{
				if(image[i,row] != FloatBitmap.White)
				{
					nBlackPixels++;
				}
			}

			return nBlackPixels;
		}
		public void CountBlackNeighboursHelperTest()
		{
			
			FloatBitmap bitmap = new FloatBitmap(5,5);
			bitmap[1,1] = FloatBitmap.Black;
			bitmap[1,2] = FloatBitmap.Black;
			bitmap[2,3] = FloatBitmap.Black;
			
			int res11 = CountBlackNeighboursHelper.BlackNeighbours(bitmap,1,1);
			int res12 = CountBlackNeighboursHelper.BlackNeighbours(bitmap,1,2);
			
			Assert.AreEqual(1,res11, "Pixel (1,1)");
			Assert.AreEqual(2,res12, "Pixel (1,2)");
		}
示例#28
0
        /// <summary>
        /// Gira 90 grados una imagen de forma no destructiva.
        /// </summary>
        /// <returns>
        /// La copia de la original, girada.
        /// </returns>
        public FloatBitmap Rotate90()
        {
            FloatBitmap res = new FloatBitmap(this.Height, this.Width);

            for (int i = 0; i < this.Width; i++)
            {
                for (int j = 0; j < this.Height; j++)
                {
                    res[j, Width - i - 1] = this[i, j];
                }
            }

            return(res);
        }
		/// <summary>
		/// Cuenta el numero de cambios blanco-negro en una imagen en la
		/// fila indicada.
		/// </summary>
		/// <param name="image">Imagen sobre la que se trabaja</param>
		/// <param name="row">Fila a analizar</param>
		/// <returns>Numero de cambios de color</returns>
		public static int NumColorChangesRow(FloatBitmap image, int row) 
		{
			
			int nChanges=0;

			for(int i=1; i<image.Width; i++) 
			{
				if(image[i,row]!=image[i-1,row])
				{
					nChanges++;
				}
			}
			return nChanges;
		}
		/// <summary>
		/// Cuenta el numero de cambios blanco-negro en una imagen en la
		/// columna indicada.
		/// </summary>
		/// <param name="image">Imagen sobre la que se trabaja</param>
		/// <param name="column">Columna a analizar</param>
		/// <returns>Numero de cambios de color</returns>
		public static int NumColorChangesColumn(FloatBitmap image, int column) 
		{
			int nChanges=0;

			for(int j=1; j<image.Height; j++) 
			{				
				if(image[column,j] != image[column,j-1])
				{
					nChanges++;
				}
			}

			return nChanges;
		}
		/// <summary>
		/// Cuenta el numero de pixeles negros en una imagen en la
		/// columna indicada.
		/// </summary>
		/// <param name="image">Imagen sobre la que se trabaja</param>
		/// <param name="column">Columna a analizar</param>
		/// <returns>Numero de pixeles negros</returns>
		public static int NumBlackPixelsColumn(FloatBitmap image, int column) 
		{
			
			int nBlackPixels=0;

			for(int i=0; i<image.Height; i++) 
			{
				if(image[column,i] != FloatBitmap.White)
				{
					nBlackPixels++;
				}
			}

			return nBlackPixels;
		}
		/// <summary>
		/// Este metodo se invoca para adelgazar una imagen.
		/// </summary>
		/// <param name="image">
		/// La imagen que queremos adelgazar, en formato de matriz  bidimensional.
		/// </param>
		/// <returns>
		/// La imagen adelgazada.
		/// </returns>
		public override FloatBitmap Apply(FloatBitmap image)
		{
			//Seguimos el algoritmo que aparece en Parker, reescrito en CSharp
			
			FloatBitmap im;
			int i,j;

			nrows=image.Width+2;
			ncols=image.Height+2;

			im = new FloatBitmap(nrows,ncols);
			for (i=0; i<nrows-2; i++)
				for (j=0; j<ncols-2; j++)
					im[i+1,j+1] = image[i,j];

			for (i=0; i<nrows; i++) 
			{
				im[i,0] = 1;
				im[i,ncols-1] = 1;
			}
			for (j=0; j<ncols; j++)
			{
				im[0,j] = 1;
				im[nrows-1,j] = 1;
			}

			if(presmooth)
			{
				PreSmooth(im);
			}

			ThinStentiford(im);
			
			FloatBitmap res = new FloatBitmap(nrows - 2, ncols -2);

			for (i=0; i<nrows-2; i++)
			{
				for (j=0; j<ncols-2; j++)
				{
					res[i,j] = im[i+1,j+1];
				}
			}
			
			return res;
		}
		/// <summary>
		/// Obtiene la coordenada superior del minimo rectangulo que contiene
		/// todos los pixeles negros de la imagen.
		/// </summary>
		/// <param name="image">Imagen sobre la que se trabaja</param>
		/// <returns>Coordenada del borde superior del rectangulo que
		/// contiene los pixeles negros de la imagen</returns>
		/// <exception "System.ApplicationException">Lanzada si no se encuentra
		/// ningun pixel negro en la imagen</exception>
		private static int FindTop(FloatBitmap image) 
		{
			int width=image.Width;
			int height=image.Height;
			
			for(int i=0;i<height;i++)
			{
				for(int j=0;j<width;j++)
				{
					if(image[j,i]!=FloatBitmap.White)
					{
						return i;
					}
				}
			}
			
			throw new ApplicationException("No se ha encontrado ningun pixel negro en ImageBoxerHelper.FindTop()!");
		}
		public void CountColorChangesHelperTest()
		{
			
			FloatBitmap bitmap = new FloatBitmap(5,5);			
			bitmap[1,2] = FloatBitmap.Black;
			bitmap[3,2] = FloatBitmap.Black;
			
			int resC1 = CountColorChangesHelper.NumColorChangesColumn(bitmap,1);
			int resC2 = CountColorChangesHelper.NumColorChangesColumn(bitmap,2);			
			
			int resR1 = CountColorChangesHelper.NumColorChangesRow(bitmap,1);
			int resR2 = CountColorChangesHelper.NumColorChangesRow(bitmap,2);
			
			Assert.AreEqual(2,resC1,"Columna 1");
			Assert.AreEqual(0,resC2,"Columna 2");			
			Assert.AreEqual(0,resR1, "Fila 1");
			Assert.AreEqual(4,resR2, "Fila 2");

		}
		public override bool Apply(FloatBitmap image)
		{
			int x1,y1,x2,y2;
			
			try
			{
				ImageBoxerHelper.BoxImage(image,out x1,out y1,out x2,out y2);
			} catch(ApplicationException)
			{
				return false;
			}
			
			int width=(x2-x1+1);
			int height=(y2-y1+1);
			
			int tolerance = (int) (image.Width * epsilon);
			
			return height >= 2*width + tolerance;
		}
示例#36
0
        /// <summary>
        /// Convierte el <c>Pixbuf</c> pasado como parámetro a un array de float.
        /// </summary>
        /// <param name="b">
        /// Imagen bitmap a convertir.
        /// </param>
        /// <returns>
        /// Array de float bidimensional conteniendo la misma
        /// informacion de pixeles que el bitmap original, pero en escala de
        /// grises, y de forma que la coordenada Y de la imagen se almacena
        /// en la primera componente del array.
        /// </returns>
        public static FloatBitmap CreateFromPixbuf(Pixbuf b)
        {
            FloatBitmap imageRes = new FloatBitmap(b.Width, b.Height);

            int pixelStep = b.NChannels;

            // Tenemos que compensar los pixeles que se añaden para tener
            // un rowstride optimo.
            int rowstrideCompensation = b.Rowstride - pixelStep * b.Width;

            unsafe
            {
                byte *data = (byte *)b.Pixels;
                int   k    = 0;
                float color;
                for (int j = 0; j < b.Height; j++)
                {
                    for (int i = 0; i < b.Width; i++)
                    {
                        // Usamos la formula para la luminosidad NTSC
                        color =
                            data[k] * 0.299f + data[k + 1] * 0.587f + data[k + 2] * 0.114f;

                        imageRes[i, j] = color / 255.0f;

                        k += pixelStep;
                    }

                    k += rowstrideCompensation;
                }
            }

            if (imageRes.Width != b.Width ||
                imageRes.Height != b.Height)
            {
                throw new Exception("Error al crear la matriz a partir del Pixbuf");
            }

            return(imageRes);
        }
		/// <summary>
		/// Cuenta el numero de pixeles negros en la imagen que tengan
		/// <c>neighbours</c> o mas vecinos.
		/// </summary>
		/// <param name="image">Imagen sobre la que se trabaja</param>
		/// <param name="neighbours">Numero de vecinos</param>
		/// <returns>Numero de pixeles negros con <c>neighbours</c> o mas
		/// vecinos</returns>
		public static int CountPixelsXOrMoreNeighbours(FloatBitmap image, 
		                                               int neighbours)
		{
			int count=0;
			
			int width=image.Width;
			int height = image.Height;

			for(int i=0;i<width;i++)
			{
				for(int j=0;j<height;j++)
				{
					if(image[i,j]==FloatBitmap.Black
							&& CountBlackNeighboursHelper.BlackNeighbours(image,i,j)>=neighbours)
					{
						count++;
					}
				}
			}
			
			return count;
		}