PDA

Ver la Versión Completa : Trazar lineas en una imagen y Calcular Angulo???


erikmx
15-09-2008, 03:57:18
Hola a todos, les cuento un poco lo que estoy trabajando, estoy trabajndo en un proyecto de la universidad (Lic en criminalistica :))donde estamos viendo algunos metodos basicos que utilizan para calcular la velocidad del viento algun personal del ejercito y me surgio la idea de ver si es posible pasarlo a un pequeño programita en delphi hace años estudie programacion y ando oxidado por eso requiero su ayuda.

Bien el metodo consiste en observar una bandera que ondea y en base al angulo que genera hacer una pequeña operacion matematica y nos da la velocidad del viento, ejemplo vi demos que entre el asta de la bandera y la bandera se forma un angulo de 60° entonces dividimos estos 60/4= 15 MillasxHora.

Bien no tiene nada de complicado pero se me ocurrio que si cargara yo una imagen o fotografia de una bandera en un componente de imagen cuya asta es de color verde por ejemplo y la bandera es blanca o negra y en su extremo le coloco una marca de color amarillo, podria trazar una linea entre estos dos puntos??????? Me imagino que si si conosco el valor del color no??? nadamas que el problema es que no se como empezar :D

Bueno ahora supongamos que ya traze una linea entre esos puntos y se que mi vertical es el asta de color verde puedo calcular el angulo que se genera de la interseccion de estas lineas?????????? Esto lo he hecho con Photoshop o CorelDraw no recuerdo ahorita cual es...

Bueno si alguien me puede ayudar con ideas le agradecer mucho, anexe unas imagenes de una bandera espero se vean que es basicamente lo que pretendo hacer ojala me ilustren si es posible, saludos atodos.

duilioisola
15-09-2008, 09:28:14
Lo de detectar los puntos amarillos es un poco difícil, sobre todo si no es una imagen con colores planos. (un mástil verde, según sombras y luces puede tener muchísimos verdes)

Lo de calcular el ángulo es fácil: Teoría de triángulos rectángulos.

- Primero deberías tener las coordenadas x,y de los trés puntos de la imagen.
- Luego podrás calcular la distancia entre x1 y x2 y entre y1 e y2 para saber el largo de los catetos (opuesto y adyacente).
- Utilizando las funciones seno y coseno podrás averiguar toda la información que necesitas.

NOTA: Todo esto funciona, suponiendo que la foto la sacas al nivel de la bandera y perpendicular a la dirección del viento.

Neftali [Germán.Estévez]
15-09-2008, 10:04:24
Bueno, yo he entendido que tú puedes marcar los puntos sobre la imagen de la bandera.
De esa forma es bastante sencillo hacer los cálculos.
Lo que no me ha quedado claro es si los puntos los marcas sobre la imagen o ya vienen en la imagen.

De todas formas, te coloco un ejemplillo. Sobre eso si quieres haz tus pruebas o corrigeme si he entendido mal.

Ñuño Martínez
15-09-2008, 10:21:50
Vaya, parece que el milagroso programa que utilizan en la serie de ficción científica CSI-Las Vegas para obtener el número de matrícula del coche que se ve el reflejo del objetivo de la cámara que se refleja en la pupila del sujeto que se refleja en el cristal del comercio fotografiado por casualidad por un testigo que "pasaba por ahí" está más cerca de conseguirse...

Lo siento, no pude reprimirme. :D

De cualquier modo, suerte con el proyecto.

Neftali [Germán.Estévez]
15-09-2008, 11:15:40
Lo siento, no pude reprimirme.

Tienes razón. :D:D

A mi lo que me encanta es que tienen Bases de datos de todo.

El asesino pierde cualquier cosa y siempre está la Base de Datos de cordones de zapatos, la de tapones de bolígrafo, que si has perdido el tapón del bic, sale allí el año en que lo compraste, la tienda, el color y si lo llevas medio gastado o la de Logotipos de marcas de papel de water; Por si encuantras un trozo de 2 milímetros de papel, lo pasas por el programa y te identifica la marca y si has comido lentejas; Y si te has limpiado con un periódico, a partir de la tinta sale el día que lo has comprado, si has hecho el cruzigrama y la quiniela resuleta de la semana siguiente... :D

erikmx
16-09-2008, 06:35:03
Bueno, yo he entendido que tú puedes marcar los puntos sobre la imagen de la bandera.
De esa forma es bastante sencillo hacer los cálculos.
Lo que no me ha quedado claro es si los puntos los marcas sobre la imagen o ya vienen en la imagen.

De todas formas, te coloco un ejemplillo. Sobre eso si quieres haz tus pruebas o corrigeme si he entendido mal.

Gracias lo checare y comentare, la intencion es basicamente con una camara fija enfocar una bandera con los colores que sepa que son faciles de identificar los que use son ejemplos :) bien la idea es que cuando capture la imagen de mi bandera tal cual se este moviendo (incluso pense en una esfera de unicel pintada) y en base a puntos o marcas tratar de que identifique el codigo los colores y en base a eso trase una linea ente uno y otro para formar el angulo, lo que comentaba duilioisola con respecto a lo de calcular el angulo pues tiene razon es facil con las funciones de seno y coseno de delphi el detalle es conseguir esos valores que ahi es donde va la cosa.

erikmx
16-09-2008, 06:38:35
Vaya, parece que el milagroso programa que utilizan en la serie de ficción científica CSI-Las Vegas para obtener el número de matrícula del coche que se ve el reflejo del objetivo de la cámara que se refleja en la pupila del sujeto que se refleja en el cristal del comercio fotografiado por casualidad por un testigo que "pasaba por ahí" está más cerca de conseguirse...

Lo siento, no pude reprimirme. :D

De cualquier modo, suerte con el proyecto.

Tienen razon mucho de esos programas es fantasia eso ni dudarlo pero de que hay programas que permiten hacer una especie de prediccion con imagenes borrosas y extraer fragmentos super pixeleados puedo decir que si los hay pero como digo no es igual que en CSI :D

Voy a checar bien el ejemplo que amablemente me mando Neftali y les comento si funciona con todo gusto coloco el proyecto terminado con codigo para quienes quieran ver que algo tan simple se puede complicar jajajaja tanto como queramos :) un saludote a todos

duilioisola
16-09-2008, 07:50:32
Un algoritmo que te podría servir:

Si el color es poco comun (cielo azul, bandera negra y marcas amarillas):

vas sumando la cantidad de color que hay en cada linea del color de la marca (pixeles amarillos).
vas sumando la cantidad de color que ha de cada columna del color de la marca.

Tendrás dos vectores.


linea 1 2 3 4 5 6 7 8 9 10
color 0 0 0 0 2 3 1 0 0 0

columna 1 2 3 4 5 6 7 8 9 10
color 0 0 0 1 3 2 0 0 0 0

Por lo tanto la marca está aproximadamente en la linea 5 y en la columna 4

Si logras 4 puntos, obtendrás un rectángulo y con el podrás calcular el ángulo. Si obtienes una línea, será un viento de la OSTIA!!! ;)

Neftali [Germán.Estévez]
16-09-2008, 10:35:37
...la idea es que cuando capture la imagen de mi bandera tal cual se este moviendo (incluso pense en una esfera de unicel pintada) y en base a puntos o marcas tratar de que identifique el codigo los colores y en base a eso trase una linea ente uno y otro para formar el angulo...

Vale, ahora entendí mejor. En un principio creí que querías trazar las líneas de forma manual.

...pensando...

Ñuño Martínez
16-09-2008, 10:46:33
El mayor problema que le veo es identificar los puntos (pixels) que "pertenecen" a la imagen de la bandera y cuales no. La mayor dificultad que le veo es detectar el "color" ya que este varía dependiendo de la iluminación. Claro que, sabiendo que la bandera no se va a mover se puede acotar bastante y facilitarlo.

Si se sabe que el fondo va a ser estático (cuidado con los pájaros y las nubes...) se podría "enmascarar" la bandera fácilmente simplemente comparando el color de los puntos entre dos fotogramas ya que si este cambia es que la bandera se ha movido. Claro que debería establecerse un rango de "error aceptable" de forma que si cambia el color levemente no se asuma como movimiento sino como cambio en la iluminación. Si no cambia puede asumirse que es el fondo. A partir de ahí pueden buscarse los bordes (cadenas de puntos que se han movido) y medir la diferencia.

La forma de implementarlo no la tengo muy clara, no obstante. :rolleyes:

Neftali [Germán.Estévez]
16-09-2008, 11:30:06
Bueno, una aproximación para identificar colores podría ser esta. Son una pruebas sencillas, pero básicamente o que hacer es a partir de un color de referencia, intentar identificar el mismo color (con una tolerancia) en la imagen de la bandera (en este caso).

Además intenta identificar aquellos puntos que nos servirán para calcular luego el ángulo que necesitamos.

Aquí y con la imagen que nos has dado funciona bien, el problema es que una foto real con muchos más tonos, mucho más ruido y bastante mas "imprecisa" habrá que "afinar" mucho más el algoritmo, pero supongo que te puede servir de partida.

AÑADO: Me dejé el link. (http://neftali.clubdelphi.com/temporal/Bandera2.zip):o:o:o

http://img242.imageshack.us/img242/495/imagen503xq1.png

coso
16-09-2008, 12:19:00
Hola,

yo le aplicaria un filtro de contrastre, para asi diferenciar las zonas de la bandera. Una vez esto, recorriendo otra vez la imagen se podrian recuperar todos los puntos y ponerlos en un array: encontrando el punto medio (la suma de todos los puntos partido por el numero de ellos) , el de mayor altura y a la izquierda, y el de menor a la derecha, podrias trazar la linea y tendrias una aproximacion del angulo bastante correcta.

Te dejo aqui (http://www.clubdelphi.com/foros/showthread.php?t=59392) un link en el q tratamos algo parecido para encontrar zonas y filtro de contrastes. Saludos

erikmx
16-09-2008, 19:44:42
Muchas gracias a todos Ñuño Martínez, coso, duilioisola y el buen Neftali, bien pensando en eso tiene razon la cuestion de la iluminacion podria ser un problema asi que tengo que buscar colores digamos "claros y poco variables" por ejemplo si es de dia no puedo usar azul claro porque podria condundirese con las nubes, pero e pensado que la bandera podria ser completamente negra y en el extreo inferior ponerle una esfera de unicel como les habia comentado de color por ejemplo rojo o amarilla y otra en el punto donde se une con el asta, para tratar de conectarlos y el hasta podria ser del mismo color o diferente para diferenciarlo, neftali voy a checar muy bien tus amables ejemplos porque me esta dando lata mi compu y no me quiere compilar pero espero solucionarlo hoy ya que ahora si me captaste hasta donde lei la idea de esto :), gracias a todos y todo comentario es bien recibido :o

Neftali [Germán.Estévez]
17-09-2008, 10:12:18
Bueno haz las pruebas con el ejemplo y algunas fotos y modificando la tolerancia a ver qué resultados obtienes.

La imagen debes convertirla a BMP para que funcione con el ejemplo; Prueba con algunas fotos (si puedes a ver qué tal). A partir de ahí puedes mejorarlo o modificarlo a ver si mejoran los resultados.

erikmx
17-09-2008, 20:26:42
Bueno haz las pruebas con el ejemplo y algunas fotos y modificando la tolerancia a ver qué resultados obtienes.

La imagen debes convertirla a BMP para que funcione con el ejemplo; Prueba con algunas fotos (si puedes a ver qué tal). A partir de ahí puedes mejorarlo o modificarlo a ver si mejoran los resultados.

Gracias Neftali, estoy teniendo unos problemillas con mi maquina y voy a tener que formatearla pero ya cheque los ejemplos y estan muy interesantes voy a hacer pruebas fotograficas con banderas reales y a ver que pasa, lo que si note es que el color negro no lo detecta como color de asta claro que tengo que checar ya que por algo no los habilitaste :D y haber si le puedo implementar lo del primer ejmplo para que calcule el angulo :) pero sobre este ejemplo, un saludote

Neftali [Germán.Estévez]
18-09-2008, 11:30:22
lo que si note es que el color negro no lo detecta como color de asta claro que tengo que checar ya que por algo no los habilitaste

Bueno, los deshabilité simplemente para dejar el ejemplo más limpio, pero funcionan igual que el otro. Si seleccionas los colores del ASTA, CIELO y BANDERA (diferentes) te detecta todas las áreas; En realidad si lo piensas, para calcular el ángulo no necesitas detectar el ASTA, ya que si detectas bien la bandera, con eso sólo no necesitas más.

La vertical, puedes obtenerla (lo que obteníamos del ASTA):
* A partir del punto superior izquierdo de la Bandera (y trazando la vertical).
* O a partir del punto inferior izquierdo de la bandera
* O utilizando ambos.

erikmx
19-09-2008, 07:17:21
Aunque todavia mi cacharra esta com que me da lata esperare al sabado para darle su coco wash :) mientras checaba el ejmplo de neftali el cual agradesco infinitamente :D y aunque estoy checando el tipo de tela que me puede servir decidi hacer unas banderas en Paint ( mmm mas bien unas lineas y despues una rellenada jajaja ) y a simplevista no detecta el pixel final, o tal ves es que no estoy haciendo el procedimiento correcto?? ya que deberia trazar la linea como con el digujo de la primera bandera que subi pero depues no lo hace como digo igual y estoy cometiendo un error, pensando en lo que me dijo neftali nuevamente simplifique dejando solo el codigo que es el util.

http://criminalistic.org/Bandera1.jpg
(Esta es la primera que mande y parece que detecta bien todo y el angulo creo que tambien es correcto :D)

http://criminalistic.org/Bandera90GradosDetalle.JPG

(Esta es la Pseudo bandera que dibuje aproximandome a los 90 grados pero que no traza las lineas como en el anterior)

http://criminalistic.org/Bandera50GradosAproxDetalle.JPG

(Esta la hice aproximandome a los 50 grados pero no detecta el punto punto del extremo inferior lo toma antes)

Aqui dejo el archivo del programa como lo simplifique y agrege lo de calculo de angulos espero que este bien calculado :D:D:D:D con los datos que tome con los BMP que utilice como ejemplos

http://criminalistic.org/Bandera3Mod.zip

Un saludo y gracias a todos, un saludo neftali

Neftali [Germán.Estévez]
19-09-2008, 13:06:33
Antes de nada comentar que el ángulo que yo tomo para el cálculo no es el que se pinta en los dibujos (esas son líneas para delimiar vértices) sino el que forman lel ASTA (vertical) y la parte INFERIOR de la bandera.

De todas formas en el ejemplo nuevo los he pintodo en color AZUL para que se diferencie.


(Esta es la Pseudo bandera que dibuje aproximandome a los 90 grados pero que no traza las lineas como en el anterior)


En este caso el error era detectando el punto inferior/izquierdo de la bandera. CORREGIDO.


(Esta la hice aproximandome a los 50 grados pero no detecta el punto punto del extremo inferior lo toma antes)


Aquí hay un error de principiante por mi parte; Tomé en cuenta el tamaño del control Image el lugar del Canvas. CORREGIDO.

Con esos cambios parace que ahora detecta bien los vértices (ROJO) y genera bien las líneas para calcular los ángulos (AZULES); Teniendo esas dos líneas azules y basándote en ellas ya se pueden realizar los cálculos.


http://img515.imageshack.us/img515/3776/banderasrx9.png

Un saludo.

erikmx
21-09-2008, 01:34:45
Gracias Neftali por tu valiosa ayuda, y perdon por la tardanza en contestar, estoy buscando los materiales (tela) que funcionen mejor para la cuestion de que detecte bien los colores hice una pequeña prueba pero con la webcam de la compu sobre una pequeña bandera hecha de plastico (bolsa negra) pero no me funciono :) claro que la luz era de foco y lo ideal es que sea con luz solar para que la imagen salga con mejor calidad, y creo sera mejor tela para que no cree "reflejos" sobre la superficie de la bandera.

Por otro lado detecta muy bien ahora con los cambios los contornos independientemente de los colores que tenga la bandera claro una vez seleccionado el color de la misma, solo el detalle de los angulos que cheque, parece que no detecta correctamente los mismos:


// LINEAS DETECTADAS
imgBandera2.Canvas.Pen.Width := 3;
imgBandera2.Canvas.Pen.Color := clRed;
imgBandera2.Canvas.Brush.Color := clRed;

imgBandera2.Canvas.MoveTo(x1b, y1b);
imgBandera2.Canvas.LineTo(x2b, y2b);
imgBandera2.Canvas.LineTo(x1ib, y1ib);
imgBandera2.Canvas.LineTo(x1b, y1b);


// LINEAS PARA ANGULOS
imgBandera2.Canvas.Pen.Width := 5;
imgBandera2.Canvas.Pen.Color := clBlue;
imgBandera2.Canvas.Brush.Color := clBlue;

imgBandera2.Canvas.MoveTo(x1ib, y1ib);
imgBandera2.Canvas.LineTo(x2b, y2b);
imgBandera2.Canvas.MoveTo(x1ib, y1ib);
imgBandera2.Canvas.LineTo(x1ib, y2b);

// si es 90 grados o casi no se ve bien, así que alargamos...
if (Abs(y2b - y1ib) < 100) then begin
imgBandera2.Canvas.MoveTo(x1ib, y1ib);
imgBandera2.Canvas.LineTo(x1ib, y1ib + 100);
end;


//Para Calcular el Angulo
ang := ArcTan2(y2b,x1ib); // "y" para la vertical "x" para la Horizontal
angd := RadToDeg(ang);

// Resultado
Angulo.Text := IntToStr(Trunc(angd)) + '°';
Velocidad.Text := IntToStr(Trunc(angd/4));

end;


Creo que el detalle esta en la orientacion, es decir en el punto que se concidera el grado 0° o tal ves me equivoco ya que para poder calcular con el metodo de la bandera utilizan este transportador como referencia :D

http://www.criminalistic.org/Transportador.png

http://www.criminalistic.org/detalleangulo.JPG

Por cierto Neftali muchas gracias por tu paciencia :)