lunes, 14 de febrero de 2011

Análisis del flujo de movimiento en OpenCV (y 2)

He realizado una pequeña modificación para mostrar el movimiento acumulado (y representado por la flecha roja central) mediante una cruz verde.

Aparentemente se sigue el movimiento del punto de la escena, pero sólo funciona si la escena se mueve al mismo tiempo sin rotación y sin que haya un objeto en el centro que se mueva.

El código de ejemplo es:


El resultado de un movimiento satisfactorio (sin rotación ni objetos en la zona central que interfieran) puede verse en el siguiente vídeo:



Pero si realizamos rotación de la webcam o pasamos un objeto por el centro de la escena (pero no delante del objeto perseguido) entonces el algoritmo falla, ya que la información la está obteniendo del centro de la pantalla y no del objeto rastreado:



La forma de arreglar este problema es sencilla. En vez de dejar fijo el punto del fotograma anterior al que queremos calcular el flujo de movimiento lo vamos actualizando al mismo punto donde se ha calculado el desplazamiento.

El código del ejemplo mejorado es:


En el siguiente vídeo se muestra cómo ahora el algoritmo es más robusto frente a la rotación de la imagen, al movimiento de objetos en la zona central, pero no a los movimientos de objetos frente al objeto rastreado:

87 comentarios:

  1. Hola tocayo! A ver si me puedes dar un consejo u orientarme para encontrar mas información.

    Lo que busco es contar vehículos y tomar velocidades desde un vídeo de entrada.

    He estado probando pero me empiezan a salir multitud de cuadrados donde no son en realidad y me aparece como una especie de degradado en la zona de medición.

    Pensaba modificar el vídeo a contornos y probar así.

    ¿Has trabajado con algo parecido?

    Un saludo

    ResponderEliminar
  2. Hola tocayo :)

    Te cuento, precisamente parte de mi proyecto fin de máster es la vigilancia de una zona mediante un UAV. En mi caso hay muchos parámetros extras como corrección de perspectiva, compensación del propio movimiento del UAV (éste está en continuo movimiento), etc. Pero creo que los conceptos básicos del análisis final son los mismos.

    Presupongo que tu cámara es fija, por lo que podrás usar sin problemas BackgroundSubtractor:
    http://docs.opencv.org/modules/video/doc/motion_analysis_and_object_tracking.html

    En él vas agregando fotograma a fotograma las imágenes y él solito va computando lo que no es "habitual" en los fotogramas (que obviamente será algo que se superpone sobre el fondo computado).

    El efecto conseguido será el que ves en este vídeo:
    http://vimeo.com/27477093

    Aunque en él usa BackgroundSubtractorMOG2, puedes probar con los que dispone OpenCV y decidirte por el que mejor haga el trabajo que deseas.

    Recuerda que luego debes ajustar los umbrales para que no te detecte movimientos como plantas, brillos puntuales, etc.

    He hecho una pequeña búsqueda en google y te he encontrado esta página que quizá te ayude:
    http://www.openvov.com/blog/?p=161

    Suerte, ya me contarás qué tal te ha ido :)

    ResponderEliminar
  3. eres un fenómeno!!!

    Voy a ir probando esta semana y te cuento. Estoy un poco verde con openCV y tengo que ir despacio pero seguro que lo logro.

    Muchas gracias, te comentaré si me atasco o si obtengo el resultado final para que me digas que te parece o si se puede mejorar.

    Un saludo y gracias otra vez
    Óscar Castaño

    ResponderEliminar
  4. Tocayo, estoy obsesionado con esto jajaja

    Llevo toda la mañana liado y he logrado hacer esto:
    http://caroyaco.es/opencv/prueba1.png

    te dejo el fuente para que le des un vistazo
    http://caroyaco.es/opencv/main.cpp

    He probado mil cosas con el Subtractor así:
    CvBGStatModel* bg_model = cvCreateGaussianBGModel( tmp_frame );
    y en el bucle con
    cvUpdateBGStatModel( tmp_frame, bg_model );

    pero me sale todo negro, no se si es un despiste o algo que se me pasa con la versión que tengo (2.4.2)

    Supongo que si voy bien lo que me quedaría sería CvSeq* seq = cvSegmentMotion( mhi, segmask, storage, timestamp, 1 ); e ir recorriendo la secuencia, ¿no?

    No estoy muy puesto en C++ y me pierdo a veces. Soy mas de j2ee estos últimos años.

    saludos,
    O.C.

    ResponderEliminar
  5. ¿Me puedes subir el vídeo "cars_1.avi"? Si tienes Dropbox dímelo y te comparto una carpeta, o bien súbelo a mega u dime el enlace donde descargarlo.

    Acabo de llegar a casa, si me da tiempo le echo un vistazo hoy.

    ResponderEliminar
  6. Si claro, este es el enlace del vídeo
    https://mega.co.nz/#!ZwQAgb6I!b8YxZWqC7_mVCCBsIq1QWRGFcWphY1oLuWIA7zpG8i0

    No tengas prisa, me estas ayudando mucho y eso es de agradecer.

    Tengo algunas ideas para probar mañana a ver si poco a poco me va saliendo algo

    Gracias

    ResponderEliminar
  7. He probado con este código que encontré
    https://mega.co.nz/#!MlZVlTAY!L78BZGS5qZCOShtDNcvxblKj94V9qBObouZ64ECNGjw

    que usa este vídeo
    https://mega.co.nz/#!90ZUHQaI!AHQt_QYg4ve55apCDnB6K1b5E-sdCk7h7IZMqnYB-28

    pero con mi vídeo no va bien, me cuenta algunas zonas degradadas que no debe contar.
    En la línea 79 utiliza cvThreshold( diff, diff, 150, 1, CV_THRESH_BINARY ); estoy probando cambiando el umbral


    Este otro enlace
    https://mega.co.nz/#!48QSWTaT!BnYgahnQfrSDi7sSFWJ5hnK64C1AaYLcsXJto1TMTGU

    es el que me comentaste del billar utilizando BackgroundSubtractorMOG2. Este me funciona pero por lo que veo parece que los objetos se me superponen cuando salen muchos vehículos.

    La verdad es que es complicado porque llega un momento que hay un gran volumen de vehículos.

    la verdad es que estoy un poco liado ya :/

    ResponderEliminar
  8. Buenos días. Anoche hice pruebas con tu vídeo y BackgroundSubtractorMOG2 y tuve bastantes problemas debido a la poca calidad de imagen que tiene el vídeo, un problema con la ganancia automática (en un par de momentos la cámara cambia su ajuste de color y altera el fondo detectado) y algo de vibración en otros momentos (que también afecta al fondo detectado).

    La compresión CON pérdida MPEG (incluso usando H.264) siempre te deja unos artefactos alrededor de las imágenes en movimiento y de los cambios bruscos de color o iluminación que interfieren con el detector de fondo ya que considera esos cambios también parte del objeto que se mueve.

    Lo ideal es trabajar con imágenes directas de cámaras que envíen los fotogramas en formatos no comprimidos espacialmente (como JPEG). Mi webcam Creative Live! Vista IM tiene ese problema y lo noto bastante (he dejado de usarla por ese motivo).

    En caso de usar un vídeo grabado procura que tenga una buena resolución y bitrate para minimizar el impacto de la pérdida de calidad en tu algoritmo. Yo estoy probando mi código en vídeo grabado en 720p que luego reduzco a una resolución inferior tras aplicarle una pequeña máscara de desenfoque.

    En cuanto al control automático de exposición, brillo, etc, suelen perjudicar estos algoritmos si no se desactivan y se controlan externamente. También la vibración de la imagen debido a que el poste sobre el que se ha montado la cámara se mueva por el viento, tráfico, etc debe compensarse.

    Ahora estoy en el trabajo y tengo la mañana bastante complicada (reuniones, revisión de procesos y documentación, etc) pero en cuanto tenga un momento de respiro subo lo que hice anoche (el código está bastante guarreado) y algunas grabaciones de vídeo de los resultados modificando los parámentros del BackgroundSubtractorMOG2.

    Un saludo.

    ResponderEliminar
  9. Por cierto, acabo de ver en este nuevo vídeo que el reflejo de la persona que graba el vídeo también influye en la detección del fondo cada vez que cambia de posición.

    Me gusta el código de BackgroundSub.cpp que has mandado, te orientará muy bien a la hora de pasar de código C a código C++ puro.

    Te mando este pequeño trozo para que lo agregues tras la definición de "BackgroundSubtractorMOG2 mog":

    mog.nmixtures = 20;
    mog.backgroundRatio = 0.45;
    mog.fVarMin = 80;

    Jugando con esos tres parámetros conseguirás ajustar el algoritmo a tus necesidades particulares.

    ResponderEliminar
  10. Por cierto, creo que en versiones modernas hay que usar:

    mog.set("nmixtures", 20);

    ResponderEliminar
  11. La calidad no es muy buena. Creo que se puede mejorar un poco pero no mucho mas, 700x570, 1680kbps y 25 fot/s

    El problema con la vibración en los postes y el pixelado en alguna de las cámaras no creo que tenga solución.

    voy a probar esos parámetros.

    No te preocupes por tú código, lo que busco es ver si con lo que tengo se puede hacer.

    un saludo y gracias
    O.C.

    PD: a trabajar que estamos en crisis :)

    ResponderEliminar
  12. Tanto la vibración como el pixelado se pueden filtrar. El primero se consigue mediante la estabilización de la imagen (usando LK, por ejemplo, como en este artículo para detectar la vibración) como el segundo, usando filtrado temporal en vez de espacial (una vez estabilizada la imagen puede "mezclarse" con la anterior en un porcentaje dado para reducir el ruido producido por la compresión).

    La complejidad de mi proyecto precisamente es esa, el rectificado, filtrado, etc que se necesita para calcular el fondo en una imagen que no es estática.

    Un saludo.

    ResponderEliminar
  13. Por cierto, échale un vistazo a esto:
    http://www.behance.net/gallery/Vehicle-Detection-Tracking-and-Counting/4057777

    Posiblemente te solucione prácticamente todo tu problema ofreciéndote varias soluciones :) aún no he podido ver tu código y pruebas, te tendré informado.

    ResponderEliminar
  14. es justo lo que quiero hacer...
    Ahora tengo que ir a clase, cuando no trabajo estudio como los buenos :), lo voy a intentar probar luego y te cuento.

    Esta mañana el BackgroundSubtractorMOG2 me daba problemas con una librería (.dll) a ver si este me va bien a la primera.

    gracias tocayo

    ResponderEliminar
  15. este parece bueno. Aunque repite en la cuenta los mismos vehículos. He estado modificando parámetros pero lo quiero ver mas detenidamente.

    Estoy probando esto http://www.behance.net/gallery/OpenCV-C-Background-Subtraction-Library/3943089
    es una librería que tiene con una vista en java que te permite seleccionar distintos métodos de subtraction.

    cada vez me sorprende mas opencv

    tú te dedicas a esto profesionalmente o eres multiplataforma como yo???

    ResponderEliminar
  16. Creo que casi lo tengo.
    Estoy entrenándolo con positivas y negativas pero necesito opencv-createsamples y opencv-haartraining que no vienen en mi instalación. Tu los tienes por casualidad a mano? Estoy intentando compilar con cmake los fuentes pero me tira errores :/

    ResponderEliminar
  17. ¿Qué distribución de linux usas? Si usas debian o ubuntu hay un paquete con todo lo último que trae OpenCV disponible en el repositorio de JDE Robot (aunque por ahora sólo para 32 bits):
    http://ordago.gsyc.es/apt/dists/

    Si tienes un poco de maña puedes bajarte tú mismo las fuentes y compilar/instalar OpenCV.

    Voy a invertir un poco de tiempo en terminar el tutorial de Android + OpenCV, llevo mucho retraso.

    ResponderEliminar
  18. Hola, no conozco muy bien acerca de opencv pero tengo que hacer un pryecto de contar personas que entran y salen que me aconsejas tu. He visto tus proyectos y son buenos por eso te pido tu ayuda. Gracias

    ResponderEliminar
    Respuestas
    1. Hola @patychat1, tu proyecto podría implementarse fácilmente con OpenCV, pero debes separar tu proyecto en varias partes.

      1.- Detector/clasificador de objetos/personas.
      2.- Decisión del sentido de la marcha.

      En la primera parte debes hacer uso de cualquier algoritmo que te ofrece OpenCV para obtener información acerca de las personas que se están moviendo en tu imagen.

      Dependiendo de la posición de la cámara, color de fondo, si es estático o dinámico, etc se podría usar un simple extractor de fondo como te explican en:
      http://docs.opencv.org/3.1.0/d1/dc5/tutorial_background_subtraction.html#gsc.tab=0

      Posteriormente debes hacer detección de "blobs" o agrupaciones de puntos que has detectado en el algoritmo anterior:
      http://www.learnopencv.com/blob-detection-using-opencv-python-c/

      Por último necesitas implementar la lógica que haga el seguimiento a lo largo del tiempo de esas agrupaciones de puntos a lo largo de su ciclo de vida en imagen para decidir si están entrando o saliendo.

      Aquí tienes un ejemplo simple de detección de vehículos usando sustracción de fondo:
      https://github.com/andrewssobral/simple_vehicle_counting

      También puedes hacer uso de algoritmos de LBP o Haar para la búsqueda de objetos usando un clasificador. Aquí tienes la explicación de cómo funciona el sistema de entrenamiento para ambos algoritmos:
      http://docs.opencv.org/3.1.0/dc/d88/tutorial_traincascade.html#gsc.tab=0

      Y aquí un ejemplo simple de detección de caras usando Haar:
      http://docs.opencv.org/3.1.0/d7/d8b/tutorial_py_face_detection.html#gsc.tab=0

      Espero que te sea de ayuda la lectura.

      Eliminar
  19. Hola me puedes ayudar un poco mas con lo de lo blobs porque no he podido solucionar esa parte. Gracias

    ResponderEliminar
    Respuestas
    1. Para empezar necesitaría conocer el lenguaje de programación que usas, presupongo C++, pero quizá estés usando C, Java o Python y necesito saberlo para buscarte enlace a los ejemplos de la documentación oficial u otros proyectos que tengan implementado algo similar. Esa sería la forma más rápida de ayudarte.

      Eliminar
  20. Estoy haciendo en Opencv, creo que es lenguaje C. Lo que ya tengo es la primera parte, el extractor de fondo. Gracias

    ResponderEliminar
  21. hola muy buenos tus tutoriales de opencv yo quiero contar objetos redondos que aparescan en una imagen pero me esta costando mucho, el lenguaje de programacion que uso es python y estoy verde en esto de opencv. muchas gracias por la informacion que compartes.

    y algunas cosillas mas que quiero hacer es que reconosca mi propio rostro y como crear los patrones o los haar cascade.

    ResponderEliminar
    Respuestas
    1. ¿Qué necesitas? ¿Documentación o que te eche una mano a echar a andar el código?

      Eliminar
    2. necesito documentacion y codigo si es posible que ya este con comentarios para compararlo con el mio a ver en que estoy fallando

      Eliminar
  22. me descarge la documentacion oficial que trae ya ejemplos tengo instalado el opencv y me tira este error al ejecutar el archivo find_obj.py : img1 - 25 features, img2 - 412 features
    OpenCV Error: Assertion failed (count >= 4) in cvFindHomography, file /build/buildd/opencv-2.3.1/modules/calib3d/src/fundam.cpp, line 235
    bruteforce match:
    Traceback (most recent call last):
    File "find_objeto.py", line 96, in
    vis_brute = match_and_draw( match_bruteforce, 0.75 )
    File "find_objeto.py", line 89, in match_and_draw
    H, status = cv2.findHomography(matched_p1, matched_p2, cv2.RANSAC, 5.0)
    cv2.error: /build/buildd/opencv-2.3.1/modules/calib3d/src/fundam.cpp:235: error: (-215) count >= 4 in function cvFindHomography


    he buscado en la web informacion para solucionar eso pero no la encuentro me podrias ayudar?

    ResponderEliminar
  23. ya solucione casi todo lo anterior ahora solo me queda arreglar un error cuando pongo en la terminal: python find_obj.py eyel.jpg eyelets.jpg

    Lo que me dice es:
    Feature-based image matching sample.

    Note, that you will need the https://github.com/Itseez/opencv_contrib repo for SIFT and SURF

    USAGE
    find_obj.py [--feature=[-flann]] [ ]

    --feature - Feature to use. Can be sift, surf, orb or brisk. Append '-flann'
    to feature name to use Flann-based matcher instead bruteforce.

    Press left mouse button on a feature point to see its matching point.

    Traceback (most recent call last):
    File "find_obj.py", line 155, in
    detector, matcher = init_feature(feature_name)
    File "find_obj.py", line 43, in init_feature
    detector = cv2.BRISK_create()
    AttributeError: 'module' object has no attribute 'BRISK_create'

    ResponderEliminar
    Respuestas
    1. informacion adicional uso ubuntu 12.04 con python 2.7 con la version de opencv 2.4.9 y otra cosa que me gustaria es tomar fotos con la webcam y leer las letras que aparescan en una imagen.

      muchas gracias por tu ayuda

      Eliminar
  24. Oscar garcia muchas gracias por toda la informacion que compartes, primero antes de pedirte ayuda mejor voy a aprender tus tutoriales despues si tengo alguna duda especifica te lo hare saber, asi que muchas gracias

    ResponderEliminar
    Respuestas
    1. Gracias por tus comentarios y siento no haber tenido tiempo la semana pasada para leer tus comentarios.

      En cuanto al script de python que no te funciona, parece que tu versión de OpenCV no tiene BRISK implementado. No sé cómo mirar en la documentación de Python cuándo fue implementada y/o a partir de qué versión está disponible, lo siento.

      Mis tutoriales comenzaron siendo ejemplos 100% C para ser usados en mis prácticas de robótica. Me gusta compartir mis conocimientos y en aquella época disponía de más tiempo libre para hacerlo. Posteriormente migré todo el código a C++, y por último he hecho algunas implementaciones en Java para Android, pero nunca he usado OpenCV en python, por lo que mi ayuda con ese lenguaje es limitada.

      En la actualidad mi tiempo disponible es limitado (la paternidad es mi prioridad), pero siempre que encuentro tiempo sigo subiendo código a mi repositorio de github o publicando alguna que otra cosa en este blog. GRACIAS POR LEERLO y me alegra saber que aún sigue siendo de utilidad :)

      Eliminar
  25. Hola ya consegui detectar el movimiento a traves de los blob, como podria crear la logica para definir la entrada y salida. Estaba pensando en una red neuronal.

    ResponderEliminar
    Respuestas
    1. Creo que usar una red neuronal para resolver el problema puede ser matar moscas a cañonazos.

      Para empezar deberías "enseñar" (o entrenar) a tu sistema (o modelo) a predecir la trayectoria basado en parámetros. ¿Qué parámetros usarás? ¿trayectoria del objeto o recorrido a lo largo del tiempo?

      Quizá, para una implementación y resultados rápidos deberías usar un algoritmo sencillo basado en dos umbrales.

      La zona central entre los dos umbrales es la que marca la frontera de estar "dentro" o "fuera". Los dos umbrales, uno a cada extremo de esa zona, definen la entrada o salida del sistema dependiendo del orden en el que se atraviesen.

      La implementación más sencilla detectará cuándo un objeto pasa la frontera exterior por primera vez, marcando su origen y posible destino (la frontera del extremo contrario). Cuando alcance el umbral contrario se contará una entrada o salida dependiendo del sentido en el que hayan pasado las fronteras.

      Implementarlo con una única línea que marca la frontera te podría traer problemas de histéresis. Los "saltos" en la detección de un objeto que lo haga saltar de un lado al otro de la línea de la frontera, contando entradas y salidas continuas espurias (falsos positivos).

      Ya me contarás por qué te decantas. Suerte y un saludo.

      Eliminar
  26. Tengo que hacer con una red neuronal, ya que eso es lo que pide el proyecto. Por favor ayúdeme en este tema.

    ResponderEliminar
    Respuestas
    1. Hacerlo por una red neuronal requiere del estudio de varias cosas:

      1.- ¿Qué tipo de datos de entrada vamos a tener en cuenta para decidir si entra o sale un objeto seguido?
      2.- ¿En qué momento cuento un objeto como que ha entrado o salido del sistema completamente?
      3.- ¿Cómo tomo los valores de entrenamiento?
      4.- ¿Cómo compruebo la fiabilidad y/o reentreno a la red con nuevos datos?

      El primer punto es el más importante, define qué datos son los que se introducirán en la red neuronal para esperar una predicción.

      Por ejemplo, se podría introducir un cv::Mat con las últimas 10 posiciones (x,y) que ha recorrido un blob, pero podría ser únicamente las últimas posiciones "y", descartando las variaciones de x si suponemos que el movimiento es vertical, o las posiciones "x" si el movimiento es horizontal.

      En el segundo punto tenemos otro dilema. Ten en cuenta que eso generaría una predicción cada 10 fotogramas, por lo que tendrías que programar la lógica de decisión de cuándo hacer caso a esa predicción. Te permitiría superponer un cartel sobre un blob que diga "entrando" o "saliendo" para que te diga qué piensa el sistema de cada blob en cualquier momento.

      Por ejemplo, tras pasar una línea imaginaria de frontera, evaluar las últimas 10 posiciones del blob para que nos prediga qué dirección va a seguir el objeto (entrar o salir). De esta manera "disparamos" la evaluación únicamente cuando el objeto atraviesa la frontera.

      El problema vuelve a ser la histéresis, el objeto puede "saltar" una y otra vez a ambos lados de la frontera.

      Cuando tengas más o menos pensados los dos primeros puntos vienen los últimos dos, no menos importantes, ya que deberás entrenar tu sistema con datos que hayas tomado en escenarios de pruebas en los que tú realmente sabes si el objeto seguido ha entrado o salido del sistema, de modo que puedas "alimentar" la red neuronal enseñándole valores base sobre los que decidir en un futuro.

      Deberías hacer un seguimiento del sistema para corregir sus falsos positivos, para que aprenda de sus errores de predicción.

      OpenCV dispone de varios algoritmos de aprendizaje para ayudarte con esta tarea: CvDTree, CvNormalBayesClassifier, CvKNearest, CvANN_MLP, CvSVM, etc... El algoritmo que deberías usar si te obligan a usar redes neuronales es CvANN_MLP: http://docs.opencv.org/2.4/modules/ml/doc/neural_networks.html#cvann-mlp-train

      En la fase de "create" deberás decidir el número de capas, teniendo en cuenta que la primera define los parámetros de entrada de tu sistema (si decides enviar únicamente la secuencia de los 10 últimas posiciones x o y, sería 10) y la última capa debería tener sólo un elemento, que deberá decidir el sentido del objeto (por ejemplo -1 para salir y 1 para entrar, de modo que una predicción superior a 0 sería entrar y menor sería salir).

      Espero que te ayude un poco todo este chorretón de literatura que te he soltado :)

      Eliminar
    2. Por cierto, sólo he hecho una práctica haciendo uso de algoritmos de aprendizaje (y no explícitamente de redes neuronales), por lo que no tengo la suficiente experiencia en ellos, siento no poder ser de mayor ayuda en ese tema.

      Este verano tengo como meta, entre otras cosas, extender mis conocimientos en algoritmos de aprendizaje/clasificación, quizá si me animo adelante los planes y le eche un vistazo estos días. Te tendré informado (probablemente publique algo).

      Eliminar
  27. Hola podría darme su correo para poder enviarle algo de información y ver si podría ser factible utilizarla en mi proyecto.

    ResponderEliminar
  28. @oscar Garcia tengo una consulta, he estado buscando sobre comparar imagenes con opencv (en otras palabras ver si ambas imagenes tiene mucha similitud, no se si me doy a entender bien) se muy bien que tienes experiencia con C y C++ pero en python es poca, lo que quiero es solo una guia de como lo harias en c++ que instrucciones de codigo o de algooritmos para yo buscar su equivalente en python.

    Otra de mis cosas que voy a tratar de hacer es contar objetos en una imagen, como asi, por ejemplo: tengo mi archivo .xml entrenado para reconocer un objeto, digamos un lapiz y cuando tome una foto donde aparescan varios lapices entonces me diga cuantos lapices hay. solo quiero saber si es factible hacerlo porque he buscado documentacion sobre esto y no he encontrado.

    muchas gracias por tu respuestas.

    ResponderEliminar
    Respuestas
    1. Bueno, acabo de ver que buscas contar el número de lápices, en ese caso es mejor usar un detector de objetos. Te dejo este ejemplo:
      http://docs.opencv.org/3.1.0/d7/d8b/tutorial_py_face_detection.html#gsc.tab=0

      ¡Suerte!

      Eliminar
  29. Hola podría darme su correo para poder enviarle algo de información y ver si podría ser factible utilizarla en mi proyecto.

    ResponderEliminar
  30. hola @Oscar Garcia tengo este codigo el cual reconoce las diferencias en una imagen esa parte funciona bien, el detalle esta es que quiero que me diga el numero de diferencias. no se si me doy a entender bien aqui te paso el enlace del sitio donde saque el codigo, lo he modificado de varias formas y nada.

    http://robologs.net/2016/04/21/detectar-diferencias-entre-dos-imagenes-con-opencv-y-python/

    las diferencias las guarda en un array pero cuando le paso la instruccion len(que en pytho sirve para dar la cantidad de la longitud de un aray) en el print me aparecen varios mensajes con el numero de canttidades de las dimensiones del arrays de cada array donde encontro una diferencia,

    lo que quiero es que me diga se han encontrado 16 diferencias que son las que tiene la imagen del ejemplo que ejecuta el sitio web

    ResponderEliminar
    Respuestas
    1. # Este es el codigo que encontraras en la pagina en estos momentos estoy tratando de comprenderlo
      # como funciona linea por linea

      import cv2

      # programa que detecta los cambios en una imagen

      #Cargamos las dos imagenes para hacer las diferencias
      diff1 = cv2.imread('diff1.png')
      diff2 = cv2.imread('diff2.png')

      #Calculamos la diferencia absoluta de las dos imagenes
      diff_total = cv2.absdiff(diff1, diff2)

      #Buscamos los contornos
      imagen_gris = cv2.cvtColor(diff_total, cv2.COLOR_BGR2GRAY)
      contours,_ = cv2.findContours(imagen_gris,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

      #Miramos cada uno de los contornos y, si no es ruido, dibujamos su Bounding Box sobre la imagen original
      for c in contours:
      veces = 0
      if cv2.contourArea(c) >= 20:
      posicion_x,posicion_y,ancho,alto = cv2.boundingRect(c) #Guardamos las dimensiones de la Bounding Box
      cv2.rectangle(diff1,(posicion_x,posicion_y),(posicion_x+ancho,posicion_y+alto),(0,0,255),2) #Dibujamos la bounding box sobre diff1
      veces = len(c)
      print('La cantida de diferencia es: ', veces)

      while(1):
      #Mostramos las imagenes. ESC para salir.
      cv2.imshow('Imagen1', diff1)
      cv2.imshow('Imagen2', diff2)
      cv2.imshow('Diferencias detectadas', diff_total)
      tecla = cv2.waitKey(5) & 0xFF
      if tecla == 27:
      break

      cv2.destroyAllWindows()

      Eliminar
    2. @oscar garcia ya lo logre resolver, era de una manera tan simple, hehe vaya que tonto he sido solo era de crear una variable que llevara la cuenta antes del ciclo for y dentro de ese ciclo por cada iteracion del ciclo que sumara mas uno

      Eliminar
  31. @Oscar Garcia me gustaria que me ayudaras con algo que estoy bien desesperado por que lo he intentado de diversas formas y aun no lo consigo estoy usando opencv 2.3,1 y quiero crear mis propias haar casacade para detectar mis propios objetos pero no he podido.

    me he descargado el ejemplo de un blog donde te ensenan a crear los haar cascade http://coding-robin.de/2013/07/22/train-your-own-opencv-haar-classifier.html

    donde solo tienes que poner las imagenes en las carpetas donde te especifica el blog pero ni siguiendo las instrucciones lo logro conseguir ya que me da algunos errores el usa la version 2.4.5 no se si esto tendra que ver ya que uso la 2.3.1

    o me ensenas a como crear un haar cascade seria una informacion muy util como para que escribas un blog ya que hay poca documentancion sobre ello mas aun en espanol.

    ResponderEliminar
    Respuestas
    1. ya actualize mi opencv a la version 2.4.11 me llevo algo de tiempo pero ni aun asi logro crear mis propios haar cascade(archvivo .xml es el que necesito)

      Eliminar
    2. Para generar el archivo XML con los datos de entrenamiento necesitas ejecutar una utilidad que se llama "opencv_traincascade" que viene con OpenCV y suele estar en "/usr/bin/opencv_traincascade" en Ubuntu 12.04. En la página del manual (man opencv_traincascade) te viene cómo usarlo.

      Aquí tienes la documentación:
      http://docs.opencv.org/2.4/doc/user_guide/ug_traincascade.html#cascade-training

      Eliminar
    3. en el link que me pasas no ensenan como crearlo sino que como usar ese comando en especifico.

      Estoy siguiendo el ejemplo de:

      http://coding-robin.de/2013/07/22/train-your-own-opencv-haar-classifier.html

      Casi todo me ha salido bien, en la parte donde fallo es cuando ejecuto el último paso, cuando intento crear el archivo .xml que me servirá para detectar mis propios objetos:

      opencv_traincascade -data classifier -vec samples.vec -bg negatives.txt -numStages 20 -minHitRate 0.999 -maxFalseAlarmRate 0.5 -numPos 1000 -numNeg 600 -w 80 -h 40 -mode ALL -precalcValBufSize 1024 -precalcIdxBufSize 1024

      esta linea me genera un error he seguido todos los pasos bien el error que me da es:
      ===== TRAINING 0-stage =====
      <BEGIN
      POS count : consumed 1000 : 1000
      NEG count : acceptanceRatio 600 : 1
      OpenCV Error: Insufficient memory (Failed to allocate 2147481604 bytes) in OutOfMemoryError, file /build/buildd/opencv-2.3.1/modules/core/src/alloc.cpp, line 52
      terminate called after throwing an instance of 'cv::Exception'
      what(): /build/buildd/opencv-2.3.1/modules/core/src/alloc.cpp:52: error: (-4) Failed to allocate 2147481604 bytes in function OutOfMemoryError

      he investigado sobre ello y es que mi pc se queda sin ram, las imagenes que uso no superan los 50kb y estan en escala de grises, ademas tengo 169 en positivas y 500 en imagenes negativas,

      sabes de alguna forma crear estos .xml he buscado mucho y aun no lo puedo hacer.

      Has creado alguna vez un .xml(haar cascade)?

      Eliminar
    4. Tengo una teoría, y es que estás usando un sistema operativo de 32 bits en vez de 64 bits. ¿Podrías ejecutar el comando "arch" para comprobar si te devuelve "x86_64"?

      Ten en cuenta que estás pasando los siguientes parámetros al programa: "-precalcValBufSize 1024 -precalcIdxBufSize 1024" que significa "resérvame una zona de memoria de 1 GB para almacenar valores de "puntos característicos" precalculados y otra zona de 1 GB para el índice.

      Si tienes un sistema operativo de 32 bits o estás compilando usando librerías de OpenCV de 32 bits tendrás un límite de reserva de memoria de 3 GB para tu aplicación.

      ¿Podrías hacer un "cat /proc/meminfo" para mostrar la memoria de la que dispones? Este es el mío:

      redstar@nvidiastar:~$ cat /proc/meminfo
      MemTotal: 8026268 kB
      MemFree: 1100052 kB
      MemAvailable: 3301600 kB
      Buffers: 233636 kB
      Cached: 2270768 kB
      SwapCached: 5904 kB
      Active: 4176196 kB
      Inactive: 1937480 kB
      [...]

      Y mi arquitectura es de 64 bits, aunque tengo soporte de multiarquitectura para 32 bits y arquitectura arm para compilaciones cruzadas (suelo trabajar con Raspberry Pi y Orange Pi):

      redstar@nvidiastar:~$ arch
      x86_64

      redstar@nvidiastar:~$ dpkg --print-foreign-architectures
      i386
      armhf

      Eliminar
    5. ya veo asi que ese es mi problema, es verdad uso ubuntu 12.04 con 32 bits entonces me recomendarios reducir la cantidad de imagenes como a que numero, y este es el mensaje que me da al poner el comando que me indicas:

      MemTotal: 3028336 kB
      MemFree: 508552 kB
      Buffers: 474760 kB
      Cached: 892420 kB
      SwapCached: 0 kB
      Active: 1333980 kB
      Inactive: 840844 kB

      que tipo de computadora me recomendarias para crear los haarcascade? ya sea ram, disco duro, tipo de procesador?

      Eliminar
    6. Quizá sea mejor empezar reduciendo los parámetros de uso de memoria a la mitad: -precalcValBufSize 512 -precalcIdxBufSize 512

      Tu equipo está bien si pudieras usar un sistema operativo de 64 bits. Con 3 GB de RAM más 3-4 GB de intercambio tendrías memoria suficiente para trabajar con el clasificador de Haar.

      Por cierto, ¿realmente tiene tu máquina 3 GB o dispone de 4 GB pero no puedes usar toda la RAM por tener un sistema operativo de 32 bits? Hace ya tanto tiempo que uso SO de 64 bits que no he llegado a tener más de 3 GB en una máquina con 32 bits, no sé qué pasaría en ese caso (aunque supuestamente con las extensiones PAE se podría usar hasta 64 GB, pero estando aún limitada la memoria por proceso).

      Según he leído en la página de Ubuntu, desde la versión 12.04 todas las versiones de 32 bits del núcleo llevan el parche PAE:
      https://help.ubuntu.com/community/PAE

      Eliminar
    7. @Oscar Garcia voy a probar a ver si me crea el archivo .xml con los datos que me has pasado, mi pc tiene solo 3 gb de ram, aunque planeo comprarme una de escritorio ya que esta me esta dando fallas en el teclado(tengo que anexarle uno usb para escribir ya que el que trae no le funcionan varias), al igual que el mouse.

      ademas se me calienta la pc facilmente, por eso tengo planeado comprarme una pc nueva.

      por eso la pregunta de como seria la pc ideal para correr este tipo de programas que piden muchos recursos? haz creado tu propio haar cascade? que recursos tiene tu pc?

      muchas gracias por tu ayuda! :)

      Eliminar
    8. muchas gracias por tu indicacion de reducir la cantidad de memoria a usar. ahora el problema es mi proppia pc que es lenta para procesar 25 iamgenes positivas y 100 negativas me dice que en 22 horas estara listo el haar cascade hehe mucho tiempo le voy a reducir la cantidad a 5 a ver como me va xxD gracias por tu ayuda

      Eliminar
    9. Perdona la tardanza en responder, he estado unos días de vacaciones :)

      Mi portátil es un i5-2450M (segunda generación) a 2.5/3.1 GHz con 8 GB de RAM, el PC del trabajo es otro i5-3470 (tercera generación a 3.2 GHz) también con 8 GB y el sobremesa de mi casa es un viejo AMD Phenom 4X a 2.4 Ghz y sólo 4 GB de RAM. Pero por desgracia nunca he ejecutado el comando en mis propios equipos (aunque podría hacer la prueba).

      La práctica de Haar la hice hace cerca de 7-8 años para la asignatura de visión artificial (creo recordar) y recuerdo que tardaba muchísimo (allí creo recordar que tenían 2 GB por equipo), pero lo que hacía era conectarme en remoto a cualquier ordenador de la granja y dejar el proceso corriendo en segundo plano.

      Lanzaba el comando a mediado/final de la clase (a veces el viernes noche para que no me reiniciaran el PC en clase por lentitud, jeje) y a la semana siguiente por la tarde al volver a clase los resultados estaban allí, recuerdo que el número de horas estimado era muy elevado, enorme, pero no recuerdo números, han pasado muchos años, pero 22 horas en 32 bits y con sólo 512 MB de caché no me parece exagerado.

      Eliminar
  32. Hola me he decidido por hacer lo de los umbrales, me podrias ayudar con eso.

    ResponderEliminar
    Respuestas
    1. @patychat1 me podrias ayudar, quiero crear mis propios haar cascade (los .xml) ya que quiero detectar mis propios objetos y no puedo hacerlo hay poca documentacion y la que hay casi no le entiendo aunque siga los pasos que ellos indiquen no se porque da errores,

      Uso python 2.7 con opencv 2.4.11 en ubuntu 12.04

      los ejemplos que estoy siguiendo es de este link:

      http://coding-robin.de/2013/07/22/train-your-own-opencv-haar-classifier.html

      llevo varios dias en ello y aun no puedo

      Eliminar
    2. Lo siento mucho pero yo tampoco tengo mucha experiencia en esto, por eso busco ayuda aqui, ademas no he trabajado en python.

      Eliminar
    3. Siento la tardanza en responder, estaré bastante ausente durante unos días más. ¿Qué tienes hecho con los umbrales? ¿Tienes algo publicado (un repositorio de github o un gist, por ejemplo) para echarle un vistazo?

      Yo también tengo poca experiencia con python (me repele bastante usarlo y si no fuera porque en la universidad lo requieren no lo usaría para nada).

      Eliminar
    4. @Oscar Garcia porque no te gusta python? si es por rendimiento es razonable ya que c++ al ser un lenguaje compilado corre mas rapido! en cambio python es mucho mas facil de leer y entender el codigo(al menos eso pienso yo, no se si piensas lo contrario) yo conosco de c++ porque en el colegio me lo ensenaron(aunque no de manera avanzada) pero prefiero python porque ejemplo:con un mini programa de 25 lineas de codigo, en c++ seria como de unas 100 o mas.

      aparte de que la sintaxis de python me parece mucho mas comprensible que la de c++

      que opinas sobre esto? o estoy en lo correcto?

      Eliminar
    5. No se trata de rendimiento, si no de estructura del código.

      Mis orígenes fueron BASIC, LOGO, ensamblador, pascal, C, Java, PHP, etc... exceptuando los lenguajes puramente lineales como BASIC o ensamblador, todos disponen de un método de enmarcar los bloques funcionales de una manera clara e inequívoca.

      Sin embargo, aún recuerdo los quebraderos de cabeza que creaban en clase los tabuladores en python... ¿a quién se le ocurrió la brillante idea de agrupar mediante "nivel" de tabulación? en el 80% de los casos, los problemas del código que se presentaban eran simples sustituciones que había hecho el editor (o errores humanos) de un tabulador en lugar de 2-4-8 espacios en blanco (dependiendo de cómo tuvieran configurado el editor).

      El código es fácil de entender y leer dependiendo del estilo de programación, no del lenguaje en sí. He corregido y ayudado a muchos compañeros sus prácticas y me ha costado más o menos igual que en cualquier otro lenguaje. A veces era complicado leer su código simplemente porque lo tenía mal estructurado, no porque python fuera más fácil o difícil.

      La comparación de número de líneas no hace justicia ya que muchas veces depende de las librerías que se usen o el tipo de programa, y la diferencia de lineas también suele ser por las llaves u otros métodos de agrupación de bloques funcionales (clases, funciones, definición de tipos de datos, etc).

      En la actualidad uso muy poco python (tenemos únicamente una aplicación corriendo en django en producción), pero la aprensión proviene de la rabia de que tantísimos fallos que he arreglado provinieran de las tabulaciones. Es la primera vez que me he topado con un lenguaje que haya provocado tantos problemas sólo por la forma en la que se estructura.

      Un saludo.

      Eliminar
    6. entiendo perfectamente tus motivos, yo tambien tengo ese mismo problema cuando reviso codigo de otros, pero dejando de lado eso, en general me parece muy bien el lenguaje.

      Eliminar
  33. @Oscar Garcia tengo una pregunta, se que puede sonar algo sin mucha utilidad pero hay algo que he estado intentando hacer pero nohe podido, es de dibujar un rectangulo sobre una imagen pero yo quiero que el rectangulo abarque toda la imagen.

    se que te preguntaras para que quieres hacer eso, es por esta razon quiero entrenar los haar casacade uno de los argumentos para las imagenes positivas es indicarle a opencv donde se encuentra las coordenas del objeto, entonces las imagenes positivas abarcaran casi toda la imagen. pero estoy intentando hacer eso pero con las coordenas que escribo no me salen(cuadros muy chiquitos).

    entonces cuando crea el haar cascade para indicarle la coordenada de donde encontrara la imagen que deseo que identifique entonces en todas las imagenes poner de parametro el mismo valor de los puntos de coordenada, espero darme a enteder bien en lo que he dicho.

    ResponderEliminar
    Respuestas
    1. Lo siento, no he entendido muy bien lo que quieres hacer.

      Cuando dices dibujar un rectángulo sobre una imagen que abarque toda la imagen, es un rectángulo sin relleno, sólo el borde que rodee al objeto, ¿no? Esa imagen no la usarás para el aprendizaje, ¿no? Recuerda que debes dar imágenes reales: fotos sobre fondos blancos o marcados con rectángulos, perfiles del objeto, etc hacen que aprenda de imágenes irreales, que no se va a encontrar en la "vida real" nunca.

      Eliminar
    2. estuve revisando mi pregunta y vaya que me equivoque en el planteamiento de mi problema, disculpa te lo explicare de esta forma que espero a darme a entender mejor:

      para crear un archivo haar cascade necesitas de imagenes positivas en ella necesitas de un archivo llamado info en el cual no solo van el nombre de cada imagen sino que tambien las coordenadas desde la cual opencv se va enfocar para hacer el aprendizaje.

      no necesito dibujar directamente sobre la imagen sino que necesito saber las coordenadas que abarquen casi toda la imagen (como asi por ejemplo si tienes una foto de una banana y esta aparesca en casi toda la imagen lo que necesita son las coordenadas que abaquen casi toda la imagen para que opencv se enfoque solo en esa area, No se si sera relativo a la resolucion de la imagen) pero supongamos que la imagen sea de 640x480 en esa resolucion se basan todos mis ejemplos y en formato .jpg

      lo de dibujar que te puse era solo para verificar que en verdad abarcaba toda la imagen(las coordenadas que usaria para poner de parametro en el archivo info) esa imagen con el borde no lo voy aponer para el aprendizaje.

      Eliminar
    3. Sí, el archivo "info.dat". ¿Has usado gimp? Con gimp puedes hacer una selección de tu objeto y en el panel de herramientas te saldrá las coordenadas X e Y y bajo ellas el ancho y alto, justo lo que necesitas definir en el archivo info.dat, pero si lo que quieres es automatizar la visualización una a una de las imágenes y en ellas dibujar un rectángulo rojo para resaltar el ROI entonces puedes hacerlo fácilmente con la función de dibujo de OpenCV:
      http://docs.opencv.org/2.4/modules/core/doc/drawing_functions.html#rectangle

      Podrás usar directamente las coordenadas X e Y de tu archivo info.dat para seleccionar el primer punto, pero para el segundo punto deberás sumar al origen el ancho y alto. Podrás usar el operador sobrecargado "+" para realizar la suma o bien sumar uno a uno los elementos del punto (propiedades x e y de la clase).

      Eliminar
    4. muchas gracias por fin despues de jugar un rato con el gimp por fin logre hacer eso xD

      si no te molesta me gustaria tener tu twiter o facebook para agregarte, si hay algo en lo que puedo ayudarte con mucho gusto lo hare(asi podriamos contactarnos mas rapido)

      que tengas un buen dia

      Eliminar
    5. se muy bien que tienes tus obligaciones pero no te preocupes tampoco quiero quitarte tiempo, tengo conocimientos en aplicaciones web:

      Del lado del servidor(Backend): Nodejs es lo mejor que manejo aunque Django es algo que me gustaria aprender ya que se usar python muy bien, pero nodejs me va de maravilla.

      De bases de datos: Mysql(base relacional) la sintaxis de lo basico, la manejo bien
      Rethinkdb(base de datos no relacional) que esta optimizada para real time, esta es mi base de datos preferida

      Del lado del navegador(Fronted): se manejar mas que todo Angular.js(Framework de Javascript) y lo basico de Bootstrap(Framework de CSS) y lo basico de HTML5

      Asi que si necesitas ayuda con algo de lo que se, puedes preguntarme, al menos con una opinion o con codigo(Ya documentado) te puedo ayudar.

      Eliminar
    6. Yo tengo interés personal por aprender Node.js, domino javascript para interfaz desde hace mucho (angujar.js llevo usándolo apenas un par de años). Siempre he querido probar qué tal va como motor.

      A veces, cuando aprendo algo nuevo, suelo abrir un repositorio en github para meter código con lo que he aprendido. Hace unos meses aprendí a usar el framework PHP llamado SLIM (hasta la fecha había usado Symfony y sólo había "tocado" codeigniter). Aquí tienes un ejemplo:
      https://github.com/ojgarciab/angularjs-slim-crud

      En la actualidad tengo "un juguetito" a medio construir para matar el gusanillo de la electrónica (mis fuertes son la programación y la electrónica, soy de los que disfrutan "cacharreando"): https://github.com/ojgarciab/ioio-4wd-robot

      Pero he tenido que ir marcando todos mis proyectos empezados como "estancados" debido a una crisis temporal de falta de tiempo libre ;)

      Eliminar
  34. hola @Oscar Garcia tengo una pregunta que podria parecer algo tonta(pero necesito tu opinion para salir de dudas) hay alguna diferencia en usar imagenes en formato .jpg .jpeg o png para hacer el haar cascade

    por ejemplo: alguno de estos formatos tiene alguna ventaja para opencv para leerlas mas rapido, o para el haar cascade mejorar los aciertos o algo por estilo.

    disculpame si te confundido, hasta yo tambien estoy pensando como plantear mejor mi pregunta pero espero que de la forma en como lo he dicho, Me entiendas. que tengas un buen dia

    ResponderEliminar
    Respuestas
    1. para hacer el haar cascade planeo comprarme una instancia de servidor en ovh, asi que mi segunda pregunta pregunta parte de alli que especificaciones me recomendarias que comprara.

      Como asi por ejemplo: memoria ram, procesador, hehe. Me parece muy buena idea hacerlo desde ahi ya que no necesitaria usar mi propia pc ni comprarme una nueva(ya que me resultaria muy cara) si alquilo una que me cuesta 34 dolares mensuales me dan lo siguientes recursos:

      Procesador: 2 vCores x 3,1 GHz
      Memoria ram: 7 GB
      Disco Duro: 100 GB SSD (no RAID) [se que no es tan necesario para hacer el haar cascade pero igual te lo informo :) ]

      que te parece? es buena idea!?

      Eliminar
    2. este es link te lo recomiendo si alguna vez necesites montar una web o una aplicacion completa

      https://www.ovh.com/us/es/cloud/instances/

      Eliminar
    3. Muchísimas gracias por tu recomendación. Soy cliente de OVH hace años :)

      Por ese presupuesto te puedes encontrar cosas mucho mejor en su gama "baja" kimsufi:
      http://www.kimsufi.com/es/servidores.xml

      No disponen de RAID, ni tienes ancho de banda garantizado, y los equipos son de generaciones anteriores que las de soyoustart (gama media) o ovh (gama alta o empresarial).

      Te puedes "pillar" un Core™ i5-3570s con 4 cores reales a 3.1 GHz+ y 16 GB de RAM por sólo 20 €/mes (19,99 para ser exactos). Que tengas disco magnético o SSD en haar cascade no te va a hacer ganar o perder rendimiento en gran medida.

      En cuanto a formatos, prefiero png si son imágenes manipuladas o recortadas (cada vez que guardas en JPEG va degradándose la calidad y añadiéndose artefactos a la imagen) o la imagen JPEG original en otro caso. Los formatos .jpg y .jpeg son exactamente lo mismo, pero dominó la extensión .jpg debido a la limitación que tenían los sistemas operativos de microsoft para tener una extensión de más de 3 caracteres.

      Tengo twitter, facebook, etc... pero hace muchísimos años que no los uso, así que con dártelos no ganarías nada. Abandoné las redes sociales hace mucho ;)

      Eliminar
    4. muchas gracias no conocia de esa pagina se ve mejor en ofertas en la gama de servidores que valen mas de 12 dolares en adelante, porque los mas baratos(los de 12 para abajo) en ovh estan mejor.

      yo tengo en ovh subida una aplicacion con nodejs, pero tengo un github al cual le subire los codigos que tengo de nodejs, python con opencv, y de pequenos programas que cree para solamentente aprender la sintaxis del lenguaje(casi no tienen uso real).

      no se si lo hare manana porque hoy no puedo sali tarde del trabajo me voy a dormir dentro de poco
      asi que si necesitas ayuda con nodejs, yo te puedo mostrar como empezar(tal como me has sacado de varios apuros) soy del tipo de persona que devuelve los favores :)

      Asi que prefieres .png, muy bien en ese formato creare las imagenes :)

      el plan que me recomiendas de 19.99 no lo encuentro en cambio encontre este que da mas procesador

      Core™ i3-2130 2c / 4t 3.4 GHz+
      ram 8 GB
      disco duro 1 TB todo eso por el precio de 14,99 €/mes + IVA

      o este:
      procesador: Core™ i5-750 4c / 4t 2.67 GHz+
      memoria ram : 16 GB
      disco duro: 2 TB
      al precio que me decias: 19,99 €/mes + IVA

      Por medio de este blog es la unica manera de contactarnos, bueno yo mis redes sociales en especial twiter la he abandonado(poco la uso[cada 5 dias]) en cambio el facebook lo reviso a diario.

      Eliminar
    5. por falta de tiempo libre no he podido subir los ejemplos con el codigo ya documentado a mi github espero tenerlos subidos ya el domingo ahi te compartire el link

      Eliminar
  35. he tenido bastante trabajo estos dias pero manana empezare a subir a mi repositorio de github los ejemplos de poco a poco los ire subiendo, muchas gracias por tu ayuda

    ResponderEliminar
  36. el domingo de esta semana sin falta te subo todos los codigos que tengo en estos dias aparte de salir tarde del trabajo, el poco tiempo que me esta quedando lo estoy dedicando a unos proyectos que tengo pero ya el viernes empezare a salir temprano asi que desde el viernes empezare a subirlo

    ResponderEliminar
    Respuestas
    1. No tengas prisa, estas fechas son caóticas por las vacaciones de unos y otros :)

      Eliminar
    2. @Oscar Garcia no he podido subir los codigos completamente documentados en estos ultimos cinco dias aparte de que el trabajo aumento(pero en esta semana me ira bien xD :) ) he estado enfermo(pero no es nada grave en 3 dias mas estare como nuevo) ayer ni si quiera toque la compu no avanze en nada, asi que al menos subi varios codigos que tengo de mis proyecto algunos estan con el codigo documentado otros no pero espero muy pronto modificarlos.

      quizas en estos dias te pregunte de algo mas de opencv pero hasta el momento con todas las dudas que me has resuelto todo va bien muchas gracias

      espero en esta semana subir una pagina personal sobre mi(las conocidas paginas de portafolio) en ella le pondre un sistema de chat(con el si tienes alguna duda me puedes contactar) cuando la tenga en subida en mi servidor ahi te paso el link

      Eliminar
  37. @Oscar Garcia no he podido subir todos los programas que tengo hechos por mala costumbre que tenia en ese tiempo que no le ponia comentarios pero ahora poco a poco lo voy haciendo. Y ademas de que aun sigo poco enfermo pero ya en cuatro dias mas estare bien.

    Tengo dos preguntas relacionada con Opencv:

    La primera es eliminar un determinado color en opencv(por ejemplo tengo una imagen con fondo rojo en la cual estan los demas objetos que quiero detectar por medio de contornos) porque los demas elementos que quiero que detecte son de cualquier otro color menos el rojo por eso el fondo(necesito hacerlo asi porque cuando tomo una imagen con una camara de mejor resolucion o en una zona mayor iluminada entonces le afecta para hacerle la comparacion de contorno por eso necesito borrar ese color o cambiar cada pixel rojo por el amarillo o por otra tonalidad de rojo).

    La segunda es como detectar letras en opencv (por ejemplo tengo una imagen[un documento] en la cual esta descrita una informacion) lo que necesito es extraer la informacion de la imagen (como asi extraer pasarla a un archivo de texto o tenerla en una variable) para despues buscar las palabras y usarlas en el programa.

    Espero darme a entender bien en lo que te trato de exponer, Muchas gracias por tu ayuda,

    ResponderEliminar
    Respuestas
    1. en lo segundo si que tengo bastantes problemas ya que no se como hacerlo pero en lo primero algunos experimentos que he hecho ya casi me va funcionar solo tengo que investigar algunos detalles.

      Eliminar
    2. Buenos días.

      La primera pregunta quizá tenga solución sencilla usando una búsqueda de rangos de color (te recomendaría hacerlo en el espacio de color HSV):
      http://docs.opencv.org/2.4/modules/core/doc/operations_on_arrays.html#inrange

      Una vez que tengas la máscara 0 (fuera del rango) - 255 (dentro del rango), puedes hacer lo que quieras sobre la imagen original, por ejemplo aplicar una multiplicación directa (pondría a 0 todos los puntos fuera del rango de color, el resto serían multiplicados por 255). También podrías invertir la máscara, dividirla entre 255 y multiplicarla por la imagen original para eliminar el fondo (convertirlo en 0)... vamos, las opciones y el uso de la máscara correrían de tu cuenta.

      La segunda pregunta es sencilla usando clasificadores siempre y cuando el tipo de letra siempre sea el mismo (o muy parecido), pero si tienes la posibilidad échale un vistazo a la interfaz para OCR que ofrece OpenCV 3 (nunca he usado esta funcionalidad, ni OpenCV 3):
      http://docs.opencv.org/3.0.0/d4/d61/group__text.html

      Puedes elegir entre usar Tesseract o HMM. Tienes un ejemplo de ambos aquí:
      https://github.com/opencv/opencv_contrib/blob/master/modules/text/samples/webcam_demo.cpp

      Espero que te sirva de ayuda. Un saludo.

      Eliminar
    3. También he encontrado esto, que quizá te sea de mayor utilidad si sólo necesitas OCR (sabiendo que programas en python):
      https://github.com/madmaze/pytesseract

      Eliminar
    4. muchas gracias por tus consejos, ya hice funcionar lo de reconocer letras

      Eliminar
    5. Enhorabuena :)

      ¿Qué solución adoptaste? ¿OpenCV 3 y el módulo "text" o directamente la librería (envoltorio) de Tesseract para python?

      Eliminar
    6. use el modulo de Tesseract para python 2 con eso me funciono, pero un detalle que reconoce mejor los tipos de letra como el Arial, Helvetica, Oxigen pero hay algunos que ni por cerca daban las palabras.

      Con lo primero que te plantee ya lo logre hacer solo que aun no lo puedo poner en mi proyecto principal porque necesito obtener los materiales pero ya logrado el experimento, ya lo tengo resuelto

      Muchas gracias pero aunque no haya podido crear el clasificador pero en teoria puedo hacerlo, ya cuando necesite detectar mis propios objetos entonces le dedicare recursos a eso

      Eliminar
  38. buenas, necesito ayuda estoy tratando de detectar objetos en una determinada zona pero tengo problema con la estabilizacion de video ante la vibracion de la camara, lo estoy haciendo con python+opencv alguien tiene alguna sugerencia

    ResponderEliminar
    Respuestas
    1. Hola Rodolfo, bienvenido al blog.

      Puedes usar el algoritmo de Lucas-Kanade para detectar el movimiento y compensarlo moviendo la imagen acorde con él.

      Esta entrada del blog ya es muy antigua, usaba Ubuntu 10.04 con (si mal no recuerdo) OpenCV 2.1.

      Puedes encontrar un tutorial de dicho algoritmo en:
      http://docs.opencv.org/3.2.0/d7/d8b/tutorial_py_lucas_kanade.html

      Y mucho código de ejempo en python en su repositorio github oficial:
      https://github.com/opencv/opencv/tree/master/samples/python

      Estabilizar la imagen no es una tarea trivial ya que debes adaptarte al movimiento real de la cámara, para ello debes implementar un control PID. También hay que tener en cuenta que una estabilización basada en flujo de movimiento y desplazamiento puro no corregirá perspectiva y no debe usarse para algoritmos como PTAM, SLAM, etc ya que estarías falseando las proyecciones moviendo el origen de coordenadas.

      Por último, recuerda que aunque compenses correctamente el movimiento y lo estabilices, el emborronamiento de movimiento (motion blur) no podrás compensarlo fácilmente y afectará a la calidad de imagen y al resultado de la detección de imágenes. Sólo con una cámara de buena calidad con una velocidad de obturador rápida (en cámaras de baja calidad se puede compensar con mucha luz) o con un estabilizador óptico (no valdría uno digital ya que en el fondo tendrías el mismo problema) podrías compensar o minimizar ese emborronamiento.

      Eliminar