public List <string> Procesar_Circulos(Bitmap BMP) { //Módulo para encontrar los círculos en una imagen List <string> Datos = new List <string>(); //crear lista datos k almacenas los datos recopilados Rectangle RECTANGULO = new Rectangle(0, 0, BMP.Width, BMP.Height); //declaramos una variable tipo rectangulo k almacenar ala circunferenia BitmapData BMPDATOS = BMP.LockBits(RECTANGULO, ImageLockMode.ReadWrite, BMP.PixelFormat); //Bitmapdata obtiene los datos de la imagen Bitmap A = new Bitmap(BMP.Width, BMP.Height); //bitmap vacio k almacena el borde de la imagen procesada ColorFiltering FILTRO = new ColorFiltering(); //filtro k se ablicara a la imagen FILTRO.Red = new IntRange(0, 100); //recibe tonalidades de 0 a 100 en sus 3 capas FILTRO.Green = new IntRange(0, 100); FILTRO.Blue = new IntRange(0, 100); FILTRO.FillOutsideRange = false; FILTRO.ApplyInPlace(BMPDATOS); //BUSCA LOS ELEMENTOS BlobCounter ELEMENTOS = new BlobCounter(); //alamacena los elementos encontrados en la imagen ELEMENTOS.FilterBlobs = true; ELEMENTOS.MinHeight = 20; //ALTURA y alcho MINIMA del objeto ELEMENTOS.MinWidth = 20; ELEMENTOS.ProcessImage(BMPDATOS);//obtiene los elementos de la imagen Blob[] ELEMENTOSINFO = ELEMENTOS.GetObjectsInformation(); BMP.UnlockBits(BMPDATOS); SimpleShapeChecker BUSCADOR = new SimpleShapeChecker(); //PARA DETERMINAR LA FORMA DE LOS ELEMENTOS ENCONTRADOS Graphics DIBUJO = Graphics.FromImage(BMP); //PARA DIBUJAR LOS ELEMENTOS Graphics DIBUJO2 = Graphics.FromImage(A); Pen CIRCULOS = new Pen(Color.Black, 5); //CIRCULOS Pen TRIANGULOS = new Pen(Color.Black, 5); //TRIANGULOS Pen CUADRILATEROS = new Pen(Color.Black, 5); //CUADRILATEROS Pen TRAZO = new Pen(Color.Red); //'PARA SEÑALIZAR LAS FORMAS for (int i = 0; i < ELEMENTOSINFO.Length; i++) //recorremos la imagen pixel a pixel { System.Collections.Generic.List <AForge.IntPoint> PUNTOS = ELEMENTOS.GetBlobsEdgePoints(ELEMENTOSINFO[i]); //'OBTIENE LOS PUNTOS DE LA FORMA AForge.Point CENTRO = new AForge.Point(); //'CENTRO DEL CIRCULO float RADIO = new float(); //'RADIO DEL CIRCULO if (BUSCADOR.IsCircle(PUNTOS, out CENTRO, out RADIO)) // { //'SI ES UN CIRCULO dibujamos DIBUJO.DrawEllipse(CIRCULOS, (int)Math.Round(CENTRO.X - RADIO), (int)Math.Round(CENTRO.Y - RADIO), (int)Math.Round(RADIO * 2), (int)Math.Round(RADIO * 2)); // 'DIBUJA EL CIRCULO DIBUJO2.DrawEllipse(CIRCULOS, (int)Math.Round(CENTRO.X - RADIO), (int)Math.Round(CENTRO.Y - RADIO), (int)Math.Round(RADIO * 2), (int)Math.Round(RADIO * 2)); // 'DIBUJA EL CIRCULO Datos.Add(CENTRO.X + "-" + CENTRO.Y + "-" + RADIO); } } //Mostrar_Imagen A Pasar_Imagen pa = new Pasar_Imagen(Mostrar_Imagen); this.Invoke(pa, A); return(Datos); }
/// ////////////////////////////////////////////////////// private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)//funcionamiento del hilo secundario { //Recuperamos el bitmap seleccionado Size a = new Size(640, 480); Bitmap bmp2 = new Bitmap((Bitmap)e.Argument, a); //recuperamos el bitmap //Reducimos el tamaño de la imagen para hacer el procesamiento mas rápido Bitmap ImgReducida = new Bitmap((Bitmap)bmp2.Clone(), a); //Hacemos llamado a la función FiltrarColoresAzulyRojo para filtrar y resaltar los colores rojo y azul de las pelotas bmp2 = FiltrarColoresAzulyRojo(ImgReducida); //Con el nuevo bitmap hacemos llamado a la función Procesar_Circulos que nos devolverá los datos de los círculos encontrados List <string> Datos = Procesar_Circulos(bmp2); //Hacemos llamado a los delegados para pasar los datos obtenidos del procesamiento de la imagen Pasar_Datos pd = new Pasar_Datos(Mostrar_Datos); this.Invoke(pd, Datos); Pasar_Imagen pa = new Pasar_Imagen(Mostrar_Imagen); this.Invoke(pa, bmp2); double espaciocarro = 0, cordxbolaA = 0, cordxbolaB, formula = 0; try { string[] separar = Datos[Datos.Count - 1].Split('-'); // Datos.Add(CENTRO.X + "-" + CENTRO.Y + "-" + RADIO); distancia bola A y B espaciocarro = float.Parse(separar[2]) * 2 * 6; // diamentroX6pelotas tamañoX del carro cordxbolaA = float.Parse(separar[1]); // distancia bola A camara a objeto cordxbolaB = float.Parse(separar[2]); // distancia bola B formula = cordxbolaA * Math.Sin(60) + 3 * float.Parse(separar[2]) * 2; // distancia de pelota a A X sen60 + 3 diametro formula = (cordxbolaB - (formula - 3 * float.Parse(separar[2]) * 2) * Math.Sin(60) > 4) ? formula : 0; }//para saber si catch (Exception) { espaciocarro = 0; // tamaño del carro cordxbolaA = 0; // cordxbolaB = 0; formula = 0; } //Construimos la lógica para indicarle el movimiento al carrito según los datos obtenidos if (Mov) { //Verificar si es que se hizo la lectura de 2 circulos if (Hay2Circulos) { //Verificamos si la coordenada en X del centro del primer círculo es mayor if (float.Parse(lbl_C1X.Text) > float.Parse(lbl_C2X.Text)) { //Verificamos si la diferencia entre los radios de los círculos es mayor a 4 pixeles //y si el radio del primer círculo es mayor que el segundo //indicará que la pelota de la izquierda es mayor al de la derecha if ((float.Parse(lbl_Radio1.Text) - float.Parse(lbl_Radio2.Text)) > 4) { serialPort1.Write("d"); System.Threading.Thread.Sleep(TiempoPrimerGiro); serialPort1.Write("w"); System.Threading.Thread.Sleep(TiempoAvanzar); serialPort1.Write("p"); //Disminuimos los tiempos de giro y de avance del carro TiempoPrimerGiro -= DisminucionPrimerGiro; TiempoAvanzar -= DisminucionAvance; TiempoSegundoGiro += AumentoSegundoGiro; PrimerGiro = true; } else if ((float.Parse(lbl_Radio2.Text) - float.Parse(lbl_Radio1.Text)) > 4) { //Caso contrario indicará que la pelota de la derecha es mayor radio al de la izquierda serialPort1.Write("a"); System.Threading.Thread.Sleep(TiempoPrimerGiro); serialPort1.Write("w"); System.Threading.Thread.Sleep(TiempoAvanzar); serialPort1.Write("p"); //Disminuimos los tiempos de giro y de avance del carro TiempoPrimerGiro -= DisminucionPrimerGiro; TiempoAvanzar -= DisminucionAvance; TiempoSegundoGiro += AumentoSegundoGiro; PrimerGiro = true; } else { serialPort1.Write("w"); System.Threading.Thread.Sleep(3000); serialPort1.Write("p"); } } else { //Si es que la distancia es menor a 4 pixeles //el carro avanza hacia adelante serialPort1.Write("w"); System.Threading.Thread.Sleep(3000); serialPort1.Write("p"); } //Hacemos el cálculo de las distancias double radio1 = double.Parse(lbl_Radio1.Text); double Distancia1 = 4.5 * 0.3 / (radio1 / 1000); double radio2 = double.Parse(lbl_Radio2.Text); double Distancia2 = 4.5 * 0.3 / (radio2 / 1000); //Hacemos llamado al delegado para actualizar las distancias calculadas Pasar_Distancias pa2 = new Pasar_Distancias(Mostrar_Distancia); string a2 = Distancia1.ToString() + "-" + Distancia2.ToString(); this.Invoke(pa2, a2); } else { if (!FlagInicio)//cuando el vehiculo no ha hecho ningun movimiento tiene k hacer un giro //para encotrar las pelotas { if (PrimerGiro) { //Si es el primer giro hacemos un giro de 1 segundo serialPort1.Write("a"); System.Threading.Thread.Sleep(1000); serialPort1.Write("p"); PrimerGiro = false; } else { //Caso contrario hacemos giros consecutivos de 200 milisegundos serialPort1.Write("a"); System.Threading.Thread.Sleep(200); serialPort1.Write("p"); } } else { FlagInicio = false; } } } }