Tag Archives: OpenCV

e9f84349-2e02-4c69-88c7-24451e792023

Ya Contamos Personas… Ahora hagamos algo con Python

20 Abr , 2017,
Jose Nunez
, , , , ,
one comments

Muchas personas piensan que la visión computarizada es un área de la tecnología reservada para genios matemáticos japoneses.

Nada más lejos de la realidad.

Mientras que en efecto se hace uso intensivo de matemática muy avanzada, y de sistemas computacionales de última generación; la realidad es que, gracias al código abierto, existen bibliotecas y frameworks  que hace accesible estas tecnologías a todas las personas que, con una dosis adecuada de interés quieran adentrarse en este mundo tan fascinante y a la vez de vital importancia para nuestra sociedad moderna.

En esta entrega les mostramos una extensión de nuestro artículo anterior sobre “Visión Computarizada: Contando Gente con OpenCV, ROS,..” donde exploramos la creación un programa básico en lenguaje Python que haga uso modesto de los datos generados por el contador de personas.

Recordemos que ROS (Robot Operating System) es un meta-sistema operativo de tipo publicador/suscriptor que facilita la comunicacion entre diversos nodos computacionales; y que está orientado a sistemas robóticos.

Como dijimos, en el artículo anterior exploramos cómo configurar un sistema Up-Board con Ubuntu Linux, para utilizar los datos provenientes de una cámara para analizar las imagenes en tiempo real y detectar personas. Fascinante.

Ahora, basados en el tutorial básico de ROS para creación de programas Python de publicación y escucha, acá listamos los pasos básicos para la creación de publicadores y escuchadores que funcionen con ROS.

(!) Antes, tengamos en cuenta que la detección de personas que viene con opencv_apps de ROS lo que hace es buscar en las imágenes patrones que coincidan con cierta geometría rectangular alta. Por eso en la imagen destacada de este artículo vemos marcas de rectángulos donde no hay personas. Al final de este artículo hablamos del comando rosrun rqt_reconfigure rqt_reconfigure que permite ajustar parámetros “en caliente” para mejorar la precisión.

También, antes de ejecutar estos procedimientos, es probable que necesite ejecutar las instrucciones de algunos artículos anteriores que se listan en esta página: http://costaricamakers.com/?p=914 a partir del punto 4.

En caso de duda o si algo no funciona, les agradezco nos lo hagan saber en los comentarios.


PASO 1 – Primeramente creamos un espacio de trabajo de tipo catkin. Es decir la estructura básica de archivos y herramientas de un espacio de trabajo para ROS usando el sistema de construcción Catkin.

mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
cd ~/catkin_ws/
catkin_make
source devel/setup.bash

PASO 2 – Seguidamente crearemos un paquete de ROS al que llamaremos “beginner_tutorials”que no es otra cosa que un conjunto de programas que se pueden manipular mediante ROS.

cd ~/catkin_ws/src
catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
cd ~/catkin_ws
catkin_make
. ~/catkin_ws/devel/setup.bash

De nuevo, para más información sobre la creación de paquetes puede visitar el tutorial oficial en http://wiki.ros.org/ROS/Tutorials/CreatingPackage


PASO 3 – Ahora escribiremos los programas básicos de publicación y escucha.

roscd beginner_tutorials
mkdir scripts
cd scripts
wget https://raw.github.com/ros/ros_tutorials/kinetic-devel/rospy_tutorials/001_talker_listener/talker.py
chmod +x talker.py

El comando wget de la linea 4 arriba se encargará de descargar nuestro programa de python llamado “talker.py” que se encarga de publicar mensajes en un nodo denominado “chatter” que luego serán leidos desde el programa de escucha o suscriptor.

Para crear el programa de escucha usamos los siguientes comandos:

roscd beginner_tutorials/scripts/
wget https://raw.github.com/ros/ros_tutorials/kinetic-devel/rospy_tutorials/001_talker_listener/listener.py
chmod +x listener.py

Con esto se descarga el programa “listener.py” en nuestra carpeta scripts para programas de python.

Este programa escuchará datos publicados al nodo “chatter” y los mostrará en la pantalla.


PASO 4 – Pongamos a prueba estos programas.

Para esto primero compilaremos el paquete usando los siguientes comandos

cd ~/catkin_ws
catkin_make

y luego ejecutaremos ambos scripts en terminales diferentes:

rosrun beginner_tutorials listener.py
rosrun beginner_tutorials talker.py

Al ejecutarse se puede apreciar como, el listener.py no hace nada, hasta que el talker.py es ejecutado. El programa talker.py envia mensajes con un numero al tópico chatter; estos mensajes son entonces escuchados por el programa listener.py el cual los muestra en la pantalla al recibirlos. Es una dinámica muy simple.


PASO 5 – Modifiquemos el listener.py

Ahora modificaremos el programa listener.py para que en lugar de escuchar el tópico ‘chatter’ publicado por talker.py, escuche un tópico un tanto más avanzado: la cuenta de personas de nuestra cámara.

Usando el siguiente comando abrimos listener.py usando el editor gedit que viene con Ubuntu.

cd ~/catkin_ws
sudo gedit src/beginner_tutorials/scripts/listener.py

Luego reemplazamos el contenido del script con el siguiente:

#!/usr/bin/env python
# Software License Agreement (BSD License)
#
# Copyright (c) 2008, Willow Garage, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#  * Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above
#    copyright notice, this list of conditions and the following
#    disclaimer in the documentation and/or other materials provided
#    with the distribution.
#  * Neither the name of Willow Garage, Inc. nor the names of its
#    contributors may be used to endorse or promote products derived
#    from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# Revision $Id$

## Simple talker demo that listens to std_msgs/Strings published 
## to the 'chatter' topic

import rospy
from std_msgs.msg import String
from opencv_apps.msg import RectArrayStamped

def callback(data):
    rospy.loginfo(rospy.get_caller_id() + 'I AAAA  heard %s', data)

def listener():

    # In ROS, nodes are uniquely named. If two nodes with the same
    # name are launched, the previous one is kicked off. The
    # anonymous=True flag means that rospy will choose a unique
    # name for our 'listener' node so that multiple listeners can
    # run simultaneously.
    rospy.init_node('listener', anonymous=True)

    rospy.Subscriber('people_detect/found', RectArrayStamped, callback)

    # spin() simply keeps python from exiting until this node is stopped
    rospy.spin()

if __name__ == '__main__':
    listener()

Podemos observar las partes clave del programa:

  1. Linea 41: Importamos de la librería opencv_apps.msg el tipo de datos RectArrayStamped, que es el tipo de datos con que se publican las personas encontradas .
  2. Linea 44: Se muestra en consola los datos recibidos por el suscriptor. Nótese que donde dice data, podríamos poner data.rects para obtener unicamente el arreglo de rectángulos que representa a cada persona.
  3. Linea 55: Se define un suscriptor para el tópico peopledetect/found con un tipo de dato RectArrayStamped que al escuchar datos llamatrá la función callback. Esta función se define en la línea 43 y 44.

Para ejecutar este script usariamos el siguiente comando que nos mostrará los datos escuchados.

rosrun beginner_tutorials listener.py

Otros comandos que suelen ser útiles:
Para listar todos los tópicos que están manejando en la instancia de ROS: rostopic list

Para ver la información de un tópico particular: rostopic echo people_detect/found

Para configurar los tópicos activos mediante un utilitario GUI: rosrun rqt_reconfigure rqt_reconfigure


Read More…
896a8b69-9451-4bbd-be2e-ff0ff114fe4a

Visión Computarizada: Contando Gente con OpenCV, ROS, UP Board y una cámara Real Sense

7 Abr , 2017,
Jose Nunez
, , , ,
No Comments

En artículos anteriores hemos tocado el tema del kit de robótica de Intel con RealSense y UPBoard.

Como seguimiento a las instrucciones de inicio del Up Board les compartimos acá algunos comandos de ROS / LINUX para hacer uso de algunos de los ejemplos para aplicaciones de visión computarizada.


PASO 1 – Paquete OpenCV Apps

El primer paso sería la instalación de un paquete de ROS denominado “opencv_apps” mediante el siguiente procedimiento:

cd /opt
sudo apt-get install ros-kinetic-opencv-apps

PASO 2  – Ejemplo de la aplicación de detección de personas

El paquete OpenCV Apps de ROS contiene archivos de lanzamiento (.launch files) con ejemplos muy concretos sobre aplicaciones de visión computarizada.

Mediante el siguiente comando de ROS, la consola de LINUX se ubica en la ubicación del paquete OpenCV Apps:

roscd opencv_apps

Una vez en este directorio, echaremos un vistazo a la lista de archivos de lanzamiento:

cd launch
ls

El comando ls anterior lista en la consola todos los archivos .launch.

Uno de estos archivos es el denominado “people_detect.launch” el cual contiene las definiciones de ROS (en formato XML) que definen cómo tomar imágenes de una fuente (una cámara por ejemplo) y aplicar los métodos de detección de personas de OpenCV.

Para que este archivo funcione con las cámaras Real Sense, será necesario modificar este archivo “people_detect.launch” de la siguiente manera:

(!) Nota: Este procedimiento será necesario solamente una vez para una misma versión del paquete de ROS OpenCV Apps. Solo será necesario ejecutarlo nuevamente si se actualiza la versión del paquete de ROS OpenCV Apps.

Ejecute el comando gedit para editar el archivo:

sudo gedit people_detect.launch

Ubique las siguientes líneas en el archivo ver (estado inicial) y cámbielas para que luzcan como se especifica en (estado editado)

(estado inicial)

<arg name="image" default="image" doc="The image topic. Should be remapped to the name of the real image topic." />

<arg name="debug_view" default="true" doc="Specify whether the node displays a window to show edge image" />

(estado editado)

<arg name="image" default="camera/color/image_raw" doc="The image topic. Should be remapped to the name of the real image topic." /> 

<arg name="debug_view" default="false" doc="Specify whether the node displays a window to show edge image" />

PASO 3 –  Ejecución del ejemplo ROS para detección de personas

Ejecute los siguientes comandos de consola de manera individual, preferiblemente en una pestaña nueva de terminal (SHIFT CTRL  T)

1. Iniciar el nodo maestro de ROS

roscore &

2. Ubicarse en el directorio de ROS referente a la cámara Real Sense

roscd realsense_camera/

3. Lanzar (ejecutar) el procesador ROS de la cámara Real Sense

* Para una R200 use el siguiente comando: roslaunch realsense_camera r200_nodelet_default.launch &

* Para una SR300 use el siguiente comando: roslaunch realsense_camera sr300_nodelet_default.launch &

4. Ejecutar el procesador ROS para el proceso de detección de personas

roslaunch opencv_apps people_detect.launch

5. Carguemos ahora el visor de imágenes de ROS

rqt_image_view

* Este comando abre una ventana que tiene una caja de selección donde podemos elegir el canal que queremos visualizar.

 

IMG_20170304_142007

SimpleCV Hello World ++ en otros 5 minutos (Linux MINT 18)

4 Mar , 2017,
Jose Nunez
, , , , , ,
No Comments

Siguiendo nuestra serie sobre SimpleCV y como una motivación personal para aprender Python. Acá les presento un par de scripts basados en el ejemplo “Hello World” de SimpleCV.

El primero toma constantemente  una foto de una cámara y la “binariza”; es decir, la convierte cada pixel de la foto en negro o blanco dependiendo de su “posición estadística” respecto de los demás pixeles y muestra el resultado en pantalla.

El segundo toma la fotografía original, sin ser “binarizada” y la muestra en pantalla.

Al correr los scripts de manera simultánea podemos apreciar de mejor manera este filtro de binarización de la imagen.


PASO 1 – simplecv_helloworld.py

Usando un editor de texto como “xed” copiamos el siguiente programa y guardamos el archivo como “simplecv_helloworld.py”

from SimpleCV import Camera
# Initialize the camera
cam = Camera()
# Loop to continuously get images
while True:
    # Get Image from camera
    img = cam.getImage()
    img.save('/home/toruk-makto/imageport.jpg')
    # Make image black and white
    img = img.binarize()
    # Draw the text "Hello World" on image
    img.drawText("Hello World!")
    # Show the image
    img.show()

PASO 2 – simplecv_helloworld2.py

De nuevo, mediante el editor de texto copiamos el siguiente programa y guardamos el archivo como “simplecv_helloworld2.py”

from SimpleCV import Image

# Loop to continuously get images
while True:
    # Get Image from camera
    try:
        img = Image('/home/toruk-makto/imageport.jpg')
        # Draw the text "Hello World" on image
        img.drawText("Hello World!")
        # Show the image
        img.show()
    except:
        print "skip!"

PASO 3 – Ejecutar ambos scripts

En una terminal ejecutemos los siguientes dos commandos:



python simplecv_helloworld.py &

python simplecv_helloworld2.py &


Vemos como se muestran ambas imágenes “en tiempo real”

Para detener los scripts podemos digitar el comando fg(que trae el comando al “foreground de ejecución”) y luego usar las teclas CTRL C; o ejecutamos el comando sudo kill #### donde “####” corresponde al número del proceso que queremos detener; o simplemente cerramos la terminal.