public Punto(int x, int y, double anguloParcial, Minucia minucia) { Atributos atr = Atributos.getInstance(); // coordenadas del punto en cartesiano this.x = x; this.y = y; double anguloParcialEnRango = meterEnRango(anguloParcial); // Datos válidos para el cálculo del futuro descriptor de textura if (anguloParcialEnRango != 0) { this.frecuencia = (double)1 / anguloParcialEnRango; } else { this.frecuencia = Double.MaxValue; } this.orientacionRelativa = get_relative_orientation(anguloParcialEnRango, minucia.angulo); // minucia a la que está asociada el citado punto this.minucia = minucia; Matriz m = Matriz.getInstance(); if (!Funcion.seSaleDeCoordenadas(x, y, m.filas, m.cols, atr.tamEntornoPunto / 2) && Funcion.hayAlgunoEnEntorno(x, y, m.matriz, m.filas, m.cols)) { this.esValido = true; } }
void mostrarParMasFiable() { Atributos atr = Atributos.getInstance(); huellas1Final[Tratamiento.totalPasos] = new Bitmap(huellas1[0]); huellas2Final[Tratamiento.totalPasos] = new Bitmap(huellas2[0]); Graphics g1 = Graphics.FromImage(huellas1Final[Tratamiento.totalPasos]); Graphics g2 = Graphics.FromImage(huellas2Final[Tratamiento.totalPasos]); Minucia masFiable1 = gm.minuciaMasFiable1; Minucia masFiable2 = gm.minuciaMasFiable2; for (int i = 0; i < atr.radioCirculo * 4; i += 4) { g1.DrawEllipse(new Pen(Color.Green), masFiable1.x - atr.radioCirculo - i / 2, masFiable1.y - atr.radioCirculo - i / 2, atr.radioCirculo * 2 + i, atr.radioCirculo * 2 + i); } for (int i = 0; i < atr.radioCirculo * 4; i += 4) { g2.DrawEllipse(new Pen(Color.Green), masFiable2.x - atr.radioCirculo - i / 2, masFiable2.y - atr.radioCirculo - i / 2, atr.radioCirculo * 2 + i, atr.radioCirculo * 2 + i); } }
/// <summary> /// Hace la ordenación y las coloca en un vector de parejas /// </summary> void generarCorrespondenciasEnOrden() { Atributos atr = Atributos.getInstance(); //las que tienen una rotación relativa mayor que un umbral las desechamos foreach (ParejaMinuciaNormalizada pmn in normalizadas) { if (pmn.pm.rotacionRelativa > atr.umbralAngulo) { pmn.sn = 0; } } vectorParejas = normalizadas.ToArray(); Array.Sort(vectorParejas); Array.Reverse(vectorParejas); this.inicial = buscarParejaInicial(vectorParejas); minuciaMasFiable1 = inicial.pm.minucia1; minuciaMasFiable2 = inicial.pm.minucia2; transformacionT = new TransformacionT(inicial, vectorParejas); this.parejas = transformacionT.parejas; }
/// <summary> /// Constructor de la clase. Está desacoplado al máximo de la clase Atributos, esta clase /// ha sido consultada para crear el circulo a la hora de llamar al constructor /// </summary> /// <param name="indice">Círculo i-ésimo relativo a la minucia a la que él está asociado</param> /// <param name="anguloGlobal">Ángulo inferior de la minucia con respecto al origen</param> /// <param name="radio">Radio del círculo actual. Viene determinado por el usuario</param> /// <param name="numPuntos">Número de puntos que contendrá el círculo actual</param> public Circulo(int indice, double anguloGlobal, int radio, int numPuntos, Minucia minucia) { Atributos atr = Atributos.getInstance(); this.indice = indice; this.anguloGlobal = anguloGlobal; this.radio = radio; this.numPuntos = numPuntos; // minucia a la que está asociada el citado punto this.minucia = minucia; // array donde guardaremos los puntos asociados al citado círculo this.puntos = new Punto[numPuntos]; // Ahora buscaremos los puntos asociados a cada círculo for (int i = 0; i < numPuntos; i++) { // angulo del punto con respecto al centro de la minucia double anguloParcial = get_teta_polar_punto(i); // coordenadas globales del nuevo punto int nuevox = (int)(radio * Math.Sin((double)anguloParcial)) + minucia.x; int nuevoy = (int)(radio * Math.Cos((double)anguloParcial)) + minucia.y; puntos[i] = new Punto(nuevox, nuevoy, anguloParcial, minucia); } }
public static Atributos getInstance() { lock (o) { if (instancia == null) instancia = new Atributos(); return instancia; } }
bool estaMuyLejosCentro(MinuciaParcial mp) { Atributos atr = Atributos.getInstance(); double maxDistancia = ((double)atr.maxDistancia / (double)100) * atr.radioVecinos; double distancia = Funcion.distancia(mp.minuciaCentral.x, mp.minuciaCentral.y, mp.minucia.x, mp.minucia.y); return(distancia > maxDistancia); }
public Bitmap BinarizacionIterativa() { Atributos atr = Atributos.getInstance(); IterativeThreshold it = new IterativeThreshold(2, (byte)atr.umbralBinarizacion); imagen = it.Apply(imagen); umbral = it.ThresholdValue; return(imagen); }
/// <summary> /// Comprueba que la línea a partir de una minucia se prolonga longitudLinea pixels /// </summary> /// <param name="actual"></param> /// <param name="prolongacion"></param> /// <param name="longitudLinea"></param> /// <param name="g"></param> /// <returns>Devuelve verdadero si la condición es cierta</returns> bool seProlongaSuficiente(Point actual, Point prolongacion, List <Point> visitados, int longitudLinea, Graphics g) { bool dev = false; Atributos atr = Atributos.getInstance(); if (Funcion.seSaleDeCoordenadas(prolongacion.X, prolongacion.Y, filas, cols, 1)) { dev = false; } else if (longitudLinea > 0) { int x = prolongacion.X; int y = prolongacion.Y; int[,] nuevo = new int[, ] { { matriz[x - 1, y - 1], matriz[x - 1, y], matriz[x - 1, y + 1] }, { matriz[x, y - 1], 0, matriz[x, y + 1] }, { matriz[x + 1, y - 1], matriz[x + 1, y], matriz[x + 1, y + 1] } }; int difX = actual.X - prolongacion.X + 1; int difY = actual.Y - prolongacion.Y + 1; nuevo[difX, difY] = 0; int i, j; bool enc = false; Point nuevoActual = new Point(prolongacion.X, prolongacion.Y); g.DrawEllipse(new Pen(atr.colorPixelCercano), nuevoActual.X, nuevoActual.Y, 1, 1); for (i = 0; i < 3 && !enc; i++) { for (j = 0; j < 3 && !enc; j++) { if (nuevo[i, j] == 1 && !seEncuentraEnLista(visitados, x + i - 1, y + j - 1)) { enc = true; Point nuevoProlongacion = new Point(prolongacion.X + i - 1, prolongacion.Y + j - 1); visitados.Add(nuevoProlongacion); dev = seProlongaSuficiente(nuevoActual, nuevoProlongacion, visitados, longitudLinea - 1, g); } } } } else { dev = true; g.FillRectangle(atr.colorRellenoFinPixelCercano, actual.X - atr.radioCirculo / 4, actual.Y - atr.radioCirculo / 4, atr.radioCirculo / 2, atr.radioCirculo / 2); } return(dev); }
bool sonEncajables(ParAlineado pa) { Atributos atr = Atributos.getInstance(); double distancia = Funcion.distancia(pa.xT, pa.yT, pa.xDestino, pa.yDestino); bool cercanosEnDistancia = distancia <= (double)atr.radioEncaje; bool diferenciaDireccionPequeña = true; return(cercanosEnDistancia && diferenciaDireccionPequeña); }
public static Atributos getInstance() { lock (o) { if (instancia == null) { instancia = new Atributos(); } return(instancia); } }
public void agregarVecinos(List <Minucia> listaMinucias) { Atributos atr = Atributos.getInstance(); vecinos = new List <Minucia>(); foreach (Minucia minucia in listaMinucias) { if (this != minucia && Funcion.distancia(this.x, this.y, minucia.x, minucia.y) <= atr.radioVecinos) { this.vecinos.Add(minucia); } } }
Point BuscaPuntoEnDireccion(Point actual, Point dir, int maxLongitud) { Point nuevoPunto = new Point(actual.X + dir.X, actual.Y + dir.Y); int pasos = Atributos.getInstance().maxLongitudBuqueda - maxLongitud; Atributos atr = Atributos.getInstance(); if (maxLongitud > 0 && !Funcion.seSaleDeCoordenadas(nuevoPunto.X, nuevoPunto.Y, filas, cols, 1)) { if (pasos <= atr.minPasosAntesDeBuscarPunto) { nuevoPunto = BuscaPuntoEnDireccion(nuevoPunto, dir, maxLongitud - 1); } else { if (matriz[nuevoPunto.X, nuevoPunto.Y] == 0) { if (matriz[nuevoPunto.X + 1, nuevoPunto.Y] == 1) { nuevoPunto = new Point(nuevoPunto.X + 1, nuevoPunto.Y); } else if (matriz[nuevoPunto.X - 1, nuevoPunto.Y] == 1) { nuevoPunto = new Point(nuevoPunto.X - 1, nuevoPunto.Y); } else if (matriz[nuevoPunto.X, nuevoPunto.Y + 1] == 1) { nuevoPunto = new Point(nuevoPunto.X, nuevoPunto.Y + 1); } else if (matriz[nuevoPunto.X, nuevoPunto.Y - 1] == 1) { nuevoPunto = new Point(nuevoPunto.X, nuevoPunto.Y - 1); } else { nuevoPunto = BuscaPuntoEnDireccion(nuevoPunto, dir, maxLongitud - 1); } } } } else { nuevoPunto = puntoError; } return(nuevoPunto); }
void dibujaCruz(Graphics g, Minucia minucia) { Atributos atr = Atributos.getInstance(); g.DrawLine(new Pen(atr.colorCruz), minucia.x - atr.radioCirculo / 2, minucia.y - atr.radioCirculo / 2, minucia.x + atr.radioCirculo / 2, minucia.y + atr.radioCirculo / 2); g.DrawLine(new Pen(atr.colorCruz), minucia.x - atr.radioCirculo / 2, minucia.y + atr.radioCirculo / 2, minucia.x + atr.radioCirculo / 2, minucia.y - atr.radioCirculo / 2); g.DrawRectangle(new Pen(atr.colorCruz), minucia.x - atr.radioCirculo / 2, minucia.y - atr.radioCirculo / 2, atr.radioCirculo, atr.radioCirculo); }
void mostrarDatosTextura() { this.pasos[muestraDatosTextura] = new Bitmap(this.pasos[muestraTodasMinucias]); Graphics g = Graphics.FromImage(pasos[muestraDatosTextura]); Atributos atr = Atributos.getInstance(); // Selecciona las minucias que se van a imprimir por pantalla int numMinucia = 0; Random r = new Random(); List <int> lista = new List <int>(); for (int i = 0; i < atr.numEjemplos; i++) { lista.Add(r.Next(minucias.Count)); } foreach (Minucia minucia in minucias) { if (seEncuentraEnLista(lista, numMinucia)) { dibujaCruz(g, minucia); foreach (Circulo circulo in minucia.circulos) { g.DrawEllipse(new Pen(atr.colorCirculo), minucia.x - circulo.radio, minucia.y - circulo.radio, circulo.radio * 2, circulo.radio * 2); foreach (Punto punto in circulo.puntos) { g.DrawLine(new Pen(Color.Red), minucia.x, minucia.y, punto.x, punto.y); if (punto.esValido) { g.FillRectangle(atr.colorRellenoFinPixelCercano, punto.x - atr.tamEntornoPunto / 2, punto.y - atr.tamEntornoPunto / 2, atr.tamEntornoPunto, atr.tamEntornoPunto); } } } } numMinucia++; } }
void calcularDescriptorTextura() { int i, j, numPuntosTotal = 0, numPuntosValidos = 0; Atributos atr = Atributos.getInstance(); List <TexturaParcial> listaParcial = new List <TexturaParcial>(); // i recorre el número de círculos for (i = 0; i < atr.radiosL.Length; i++) { // j recorre el número de puntos de cada círculo for (j = 0; j < atr.puntosK[i]; j++) { numPuntosTotal++; Punto p1 = minucia1.circulos[i].puntos[j]; Punto p2 = minucia2.circulos[i].puntos[j]; // Para que la pareja sea válida los puntos j-ésimos // del círculo i-ésimo han de ser válidos if (p1.esValido && p2.esValido) { numPuntosValidos++; listaParcial.Add(new TexturaParcial( hallarS0(p1.orientacionRelativa, p2.orientacionRelativa), hallarSf(p1.frecuencia, p2.frecuencia))); } } } this.porcentajePuntosTextura = 100 * (double)numPuntosValidos / (double)numPuntosTotal; if (this.porcentajePuntosTextura >= (double)atr.minPorcentajeValidos) { TexturaParcial tp = hallarTexturaMedia(listaParcial); this.st = atr.w * tp.s0 + (1 - atr.w) * tp.sf; } else { this.st = 0; this.esDescriptorTexturaRelevante = false; } }
//Dada una minucia mp trasladada, mirar si existe en los vecinos del destino bool hayAlgunEncaje(MinuciaParcial mp, List <MinuciaParcial> destino) { Atributos atr = Atributos.getInstance(); bool encaje = false; foreach (MinuciaParcial mpdestino in destino) { int dx = mpdestino.minucia.x; int dy = mpdestino.minucia.y; double distancia = Funcion.distancia(dx, dy, mp.x, mp.y); if (distancia <= atr.radioEncaje) { encaje = true; break; } } return(encaje); }
void mostrarTodasMinucias() { this.pasos[muestraTodasMinucias] = new Bitmap(huella); Graphics g = Graphics.FromImage(pasos[muestraTodasMinucias]); Atributos atr = Atributos.getInstance(); foreach (Minucia minucia in minucias) { Color cFiable = Color.Black; Color cPocoFiable = Color.Black; switch (minucia.tipo) { case Minucia.Terminacion: cFiable = atr.colorTerminacionFiable; cPocoFiable = atr.colorTerminacionPocoFiable; break; case Minucia.Bifurcacion: cFiable = atr.colorBifurcacionFiable; cPocoFiable = atr.colorBifurcacionPocoFiable; break; } switch (minucia.fiabilidad) { case Minucia.Fiable: g.DrawEllipse(new Pen(cFiable), minucia.x - atr.radioCirculo / 2, minucia.y - atr.radioCirculo / 2, atr.radioCirculo, atr.radioCirculo); break; case Minucia.PocoFiable: g.DrawRectangle(new Pen(cPocoFiable), minucia.x - atr.radioCirculo / 2, minucia.y - atr.radioCirculo / 2, atr.radioCirculo, atr.radioCirculo); break; } } }
void mostrarDatosMinucia() { this.pasos[muestraDatosMinucia] = new Bitmap(this.pasos[muestraTodasMinucias]); Graphics g = Graphics.FromImage(pasos[muestraDatosMinucia]); Atributos atr = Atributos.getInstance(); // Selecciona las minucias que se van a imprimir por pantalla int numMinucia = 0; Random r = new Random(); List <int> lista = new List <int>(); for (int i = 0; i < atr.numEjemplos; i++) { lista.Add(r.Next(minucias.Count)); } foreach (Minucia minucia in minucias) { if (seEncuentraEnLista(lista, numMinucia)) { dibujaCruz(g, minucia); g.DrawEllipse(new Pen(atr.colorCirculo), minucia.x - atr.radioVecinos, minucia.y - atr.radioVecinos, atr.radioVecinos * 2, atr.radioVecinos * 2); foreach (Minucia m in minucia.vecinos) { g.FillEllipse(atr.colorRellenoFinPixelCercano, m.x - atr.radioCirculo / 4, m.y - atr.radioCirculo / 4, atr.radioCirculo / 2, atr.radioCirculo / 2); //g.DrawLine(new Pen(Color.Red), minucia.x, minucia.y, m.x, m.y); } } numMinucia++; } }
/// <summary> /// /// Busca las Terminaciones y las imprime por panatalla /// </summary> void buscarTerminaciones() { int i, j; this.pasos[busquedaTerminaciones] = new Bitmap(huella); Graphics g = Graphics.FromImage(pasos[busquedaTerminaciones]); Atributos atr = Atributos.getInstance(); for (i = 1; i < filas - 1; i++) { for (j = 1; j < cols - 1; j++) { if (matriz[i, j] == 1 && buscarEnEntorno(i, j, 2)) { añadirTerminacionPotencial(i, j); g.DrawEllipse(new Pen(atr.colorMinuciaNoFiable), i - atr.radioCirculo / 2, j - atr.radioCirculo / 2, atr.radioCirculo, atr.radioCirculo); } } } }
/// <summary> /// /// </summary> void guardarBifurcaciones() { this.pasos[guardaBifurcaciones] = new Bitmap(huella); Graphics g = Graphics.FromImage(pasos[guardaBifurcaciones]); Atributos atr = Atributos.getInstance(); foreach (Point bifurcacion in bifurcacionesFiables) { minucias.Add(new Minucia(bifurcacion.X, bifurcacion.Y, Minucia.Fiable, Minucia.Bifurcacion)); g.DrawEllipse(new Pen(atr.colorBifurcacionFiable), bifurcacion.X - atr.radioCirculo / 2, bifurcacion.Y - atr.radioCirculo / 2, atr.radioCirculo, atr.radioCirculo); } foreach (Point bifurcacion in bifurcacionesPocoFiables) { minucias.Add(new Minucia(bifurcacion.X, bifurcacion.Y, Minucia.PocoFiable, Minucia.Bifurcacion)); } foreach (Point bifurcacion in bifurcacionesNoFiables) { minucias.Add(new Minucia(bifurcacion.X, bifurcacion.Y, Minucia.NoFiable, Minucia.Bifurcacion)); } }
public static bool hayAlgunoEnEntorno(int x, int y, int[,] matriz, int filas, int cols) { Atributos atr = Atributos.getInstance(); int i, j; bool enc = false; if (matriz[x, y] == 0) { for (i = x - atr.tamEntornoPunto / 2; i <= x + atr.tamEntornoPunto / 2 && !enc; i++) { for (j = y - atr.tamEntornoPunto / 2; j <= y + atr.tamEntornoPunto / 2 && !enc; j++) { enc = matriz[i, j] == 1; } } } else { enc = true; } return(enc); }
/// <summary> /// /// </summary> /// <param name="x">i filas</param> /// <param name="y">j columnas</param> public Minucia(int x, int y, int fiabilidad, int tipo) { Atributos atr = Atributos.getInstance(); this.x = x; this.y = y; this.fiabilidad = fiabilidad; this.tipo = tipo; //calcular angulo global de minucia angulo = Funcion.anguloEntrePuntos(0, 0, x, y); circulos = new Circulo[atr.radiosL.Length]; for (int i = 0; i < circulos.Length; i++) { // Desacoplo el acceso a Atributos desde la clase círculo, así // ahora sólo se hace desde aquí. Le paso al círculo su radio y // el número de puntos que debe buscar. circulos[i] = new Circulo(i, angulo, atr.radiosL[i], atr.puntosK[i], this); } vecinos = new List <Minucia>(); }
private void inicializarAtributosPorDefecto() { atributos = Atributos.getInstance(); atributos.colorTerminacionFiable = Color.Blue; atributos.colorTerminacionPocoFiable = Color.BlueViolet; atributos.colorBifurcacionFiable = Color.Green; atributos.colorBifurcacionPocoFiable = Color.Olive; atributos.colorMinuciaNoFiable = Color.Red; atributos.colorPixelCercano = Color.Brown; atributos.colorLinea = Color.Red; atributos.colorRellenoFinPixelCercano = Brushes.Fuchsia; atributos.colorCirculo = Color.Green; atributos.colorCruz = Color.Red; atributos.radioCirculo = 8; }
void ponerPasoUltimo() { Atributos atr = Atributos.getInstance(); huellas1Final[Tratamiento.totalPasos + 1] = new Bitmap(huellas1[Tratamiento.muestraTodasMinucias]); huellas2Final[Tratamiento.totalPasos + 1] = new Bitmap(huellas2[Tratamiento.muestraTodasMinucias]); Graphics g1 = Graphics.FromImage(huellas1Final[Tratamiento.totalPasos + 1]); Graphics g2 = Graphics.FromImage(huellas2Final[Tratamiento.totalPasos + 1]); /* * int numPosiciones = atr.numEjemplos * 2; * Correspondencia[] arrayCorrespondencia = gm.correspondencias.ToArray(); * Correspondencia [] elegidas = new Correspondencia[numPosiciones]; * Random r = new Random(); * * int k = 0; * while (k < numPosiciones) * { * int nuevoPos = r.Next(arrayCorrespondencia.Length); * Correspondencia c = arrayCorrespondencia[nuevoPos]; * * if (c.minucia1.fiabilidad == Minucia.Fiable && * c.minucia2.fiabilidad == Minucia.Fiable) * { * elegidas[k++] = c; * } * } * * foreach (Correspondencia c in elegidas) * { * g1.DrawLine(new Pen(Color.Red), c.minucia1.x, c.minucia1.y, * c.minucia2.x + 512, c.minucia2.y); * g2.DrawLine(new Pen(Color.Red), c.minucia1.x - 512, c.minucia1.y, * c.minucia2.x, c.minucia2.y); * } */ bool flag = false; foreach (Correspondencia c in gm.correspondencias) { if (c.minucia1.fiabilidad == Minucia.Fiable && c.minucia2.fiabilidad == Minucia.Fiable) { flag = true; g1.DrawLine(new Pen(Color.Red), c.minucia1.x, c.minucia1.y, c.minucia2.x + 512, c.minucia2.y); g2.DrawLine(new Pen(Color.Red), c.minucia1.x - 512, c.minucia1.y, c.minucia2.x, c.minucia2.y); } } if (!flag) { foreach (Correspondencia c in gm.correspondencias) { g1.DrawLine(new Pen(Color.Fuchsia), c.minucia1.x, c.minucia1.y, c.minucia2.x + 512, c.minucia2.y); g2.DrawLine(new Pen(Color.Fuchsia), c.minucia1.x - 512, c.minucia1.y, c.minucia2.x, c.minucia2.y); } } }
/// <summary> /// /// Comprueba que las terminaciones encontradas son correctas /// Para ello recorre la línea que llega a la terminación y 4 /// más de píxeles cercanos /// </summary> void comprobarTerminaciones() { this.pasos[compruebaTerminaciones] = new Bitmap(huella); Graphics g = Graphics.FromImage(pasos[compruebaTerminaciones]); Atributos atr = Atributos.getInstance(); foreach (TerminacionPotencial tp in terminacionesPotenciales) { bool fiable = true; int gradiente = direcciones[tp.prolongacion.X - tp.actual.X + 1, tp.prolongacion.Y - tp.actual.Y + 1]; Point[] cercanos = PuntosCercanosDeOtraLinea(tp.actual, gradiente); Point cercano1 = cercanos[0]; Point cercano2 = cercanos[1]; if (cercano1 != puntoError && cercano2 != puntoError) { g.DrawLine(new Pen(atr.colorLinea), tp.actual, cercano1); g.DrawLine(new Pen(atr.colorLinea), tp.actual, cercano2); Point[] unidos1 = buscaUnidos(cercano1); Point[] unidos2 = buscaUnidos(cercano2); List <Point> visitadosTemporal; bool prol0 = false, prol1 = false, prol2 = false, prol3 = false, prol4 = false; visitadosTemporal = new List <Point>(); if (seProlongaSuficiente(tp.actual, tp.prolongacion, visitadosTemporal, atr.longitudLinea, g)) { prol0 = true; } visitadosTemporal = new List <Point>(); if (unidos1[0] != puntoError && seProlongaSuficiente(cercano1, unidos1[0], visitadosTemporal, atr.longitudLinea, g)) { prol1 = true; } visitadosTemporal = new List <Point>(); if (unidos1[1] != puntoError && seProlongaSuficiente(cercano1, unidos1[1], visitadosTemporal, atr.longitudLinea, g)) { prol2 = true; } visitadosTemporal = new List <Point>(); if (unidos2[0] != puntoError && seProlongaSuficiente(cercano2, unidos2[0], visitadosTemporal, atr.longitudLinea, g)) { prol3 = true; } visitadosTemporal = new List <Point>(); if (unidos2[1] != puntoError && seProlongaSuficiente(cercano2, unidos2[1], visitadosTemporal, atr.longitudLinea, g)) { prol4 = true; } if (prol0 && prol1 && prol2 && prol3 && prol4) { terminacionesFiables.Add(tp.actual); g.DrawEllipse(new Pen(atr.colorTerminacionFiable), tp.actual.X - atr.radioCirculo / 2, tp.actual.Y - atr.radioCirculo / 2, atr.radioCirculo, atr.radioCirculo); } else { fiable = false; } } else { fiable = false; } if (!fiable) { terminacionesPocoFiables.Add(tp.actual); g.DrawRectangle(new Pen(atr.colorTerminacionPocoFiable), tp.actual.X - atr.radioCirculo / 2, tp.actual.Y - atr.radioCirculo / 2, atr.radioCirculo, atr.radioCirculo); } } }
/// <summary> /// /// Comprueba que las bifurcaciones encontradas son correctas /// Para ello recorre las 3 líneas que salen del punto de bifurcación /// más 4 más de pixeles cercanos /// </summary> void comprobarBifurcaciones() { this.pasos[compruebaBifurcaciones] = new Bitmap(huella); Graphics g = Graphics.FromImage(pasos[compruebaBifurcaciones]); Atributos atr = Atributos.getInstance(); foreach (BifurcacionPotencial bp in bifurcacionesPotenciales) { bool fiable = true; Point[] prolongaciones = bp.prolongaciones; int gradiente1 = direcciones[prolongaciones[0].X - bp.actual.X + 1, prolongaciones[0].Y - bp.actual.Y + 1]; int gradiente2 = direcciones[prolongaciones[1].X - bp.actual.X + 1, prolongaciones[1].Y - bp.actual.Y + 1]; int gradiente3 = direcciones[prolongaciones[2].X - bp.actual.X + 1, prolongaciones[2].Y - bp.actual.Y + 1]; Point[] cercanos1 = PuntosCercanosDeOtraLinea(bp.actual, gradiente1); Point[] cercanos2 = PuntosCercanosDeOtraLinea(bp.actual, gradiente2); Point[] cercanos3 = PuntosCercanosDeOtraLinea(bp.actual, gradiente3); Point cercanoTemp1 = puntoError; Point cercanoTemp2 = puntoError; if (cercanos1[0] != puntoError && cercanos1[1] != puntoError) { cercanoTemp1 = cercanos1[0]; cercanoTemp2 = cercanos1[1]; } else if (cercanos2[0] != puntoError && cercanos2[1] != puntoError) { cercanoTemp1 = cercanos2[0]; cercanoTemp2 = cercanos2[1]; } else if (cercanos3[0] != puntoError && cercanos3[1] != puntoError) { cercanoTemp1 = cercanos3[0]; cercanoTemp2 = cercanos3[1]; } if (cercanoTemp1 != puntoError && cercanoTemp2 != puntoError) { g.DrawLine(new Pen(atr.colorLinea), bp.actual, cercanoTemp1); g.DrawLine(new Pen(atr.colorLinea), bp.actual, cercanoTemp2); Point[] unidos1 = buscaUnidos(cercanoTemp1); Point[] unidos2 = buscaUnidos(cercanoTemp2); List <Point> visitadosTemporal; bool prol0 = false, prol1 = false, prol2 = false, prol3 = false, prol4 = false, prol5 = false, prol6 = false; visitadosTemporal = new List <Point>(); visitadosTemporal.Add(prolongaciones[1]); visitadosTemporal.Add(prolongaciones[2]); if (seProlongaSuficiente(bp.actual, prolongaciones[0], visitadosTemporal, atr.longitudLinea, g)) { prol0 = true; } visitadosTemporal = new List <Point>(); visitadosTemporal.Add(prolongaciones[0]); visitadosTemporal.Add(prolongaciones[2]); if (seProlongaSuficiente(bp.actual, prolongaciones[1], visitadosTemporal, atr.longitudLinea, g)) { prol1 = true; } visitadosTemporal = new List <Point>(); visitadosTemporal.Add(prolongaciones[0]); visitadosTemporal.Add(prolongaciones[1]); if (seProlongaSuficiente(bp.actual, prolongaciones[2], visitadosTemporal, atr.longitudLinea, g)) { prol2 = true; } visitadosTemporal = new List <Point>(); if (unidos1[0] != puntoError && seProlongaSuficiente(cercanoTemp1, unidos1[0], visitadosTemporal, atr.longitudLinea, g)) { prol3 = true; } visitadosTemporal = new List <Point>(); if (unidos1[1] != puntoError && seProlongaSuficiente(cercanoTemp1, unidos1[1], visitadosTemporal, atr.longitudLinea, g)) { prol4 = true; } visitadosTemporal = new List <Point>(); if (unidos2[0] != puntoError && seProlongaSuficiente(cercanoTemp2, unidos2[0], visitadosTemporal, atr.longitudLinea, g)) { prol5 = true; } visitadosTemporal = new List <Point>(); if (unidos2[1] != puntoError && seProlongaSuficiente(cercanoTemp2, unidos2[1], visitadosTemporal, atr.longitudLinea, g)) { prol6 = true; } if (prol0 && prol1 && prol2 && prol3 && prol4 && prol5 && prol6) { bifurcacionesFiables.Add(bp.actual); g.DrawEllipse(new Pen(atr.colorBifurcacionFiable), bp.actual.X - atr.radioCirculo / 2, bp.actual.Y - atr.radioCirculo / 2, atr.radioCirculo, atr.radioCirculo); } else { fiable = false; } } else { fiable = false; } if (!fiable) { bifurcacionesPocoFiables.Add(bp.actual); g.DrawRectangle(new Pen(atr.colorBifurcacionPocoFiable), bp.actual.X - atr.radioCirculo / 2, bp.actual.Y - atr.radioCirculo / 2, atr.radioCirculo, atr.radioCirculo); } } }
Point[] PuntosCercanosDeOtraLinea(Point actual, int gradiente) { int ngra1 = 0, ngra2 = 0; Point dir1 = new Point(0, 0), dir2 = new Point(0, 0); Point[] cercanos = new Point[2]; Atributos atr = Atributos.getInstance(); switch (gradiente) { case 0: ngra1 = 2; ngra2 = 6; break; case 1: ngra1 = 3; ngra2 = 7; break; case 2: ngra1 = 0; ngra2 = 4; break; case 3: ngra1 = 1; ngra2 = 5; break; case 4: ngra1 = 2; ngra2 = 6; break; case 5: ngra1 = 3; ngra2 = 7; break; case 6: ngra1 = 0; ngra2 = 4; break; case 7: ngra1 = 1; ngra2 = 5; break; } switch (ngra1) { case 0: dir1 = new Point(0, 1); break; case 1: dir1 = new Point(-1, 1); break; case 2: dir1 = new Point(-1, 0); break; case 3: dir1 = new Point(-1, -1); break; case 4: dir1 = new Point(0, -1); break; case 5: dir1 = new Point(1, -1); break; case 6: dir1 = new Point(1, 0); break; case 7: dir1 = new Point(1, 1); break; } switch (ngra2) { case 0: dir2 = new Point(0, 1); break; case 1: dir2 = new Point(-1, 1); break; case 2: dir2 = new Point(-1, 0); break; case 3: dir2 = new Point(-1, -1); break; case 4: dir2 = new Point(0, -1); break; case 5: dir2 = new Point(1, -1); break; case 6: dir2 = new Point(1, 0); break; case 7: dir2 = new Point(1, 1); break; } cercanos[0] = BuscaPuntoEnDireccion(actual, dir1, atr.maxLongitudBuqueda); cercanos[1] = BuscaPuntoEnDireccion(actual, dir2, atr.maxLongitudBuqueda); return(cercanos); }