Ros Hydro + OpenCV – Fusionar dos imagenes con diferentes tamaños

Parto de la idea de que las referencias a OpenCV están cargadas, por lo que sólo hace falta escribir el código.

En mi caso, más que fusionar dos imágenes de diferentes tamaños partiendo de dos ficheros, me interesaba saber cómo añadir un logo a las imágenes capturadas por la Kinect (Webcam o lo que toque). Un error que he estado cometiendo era intentar cargar la imagen del logo en la función callback, que se ejecuta cuando hay una nueva imagen de Kinect en el topic camera/depth_registered/points. Si la carga del logo se hace en la función main(), entonces funciona correctamente.

En la función main(), por tanto, cargamos la imagen con el logo, que en este caso tiene un tamaño de 150×50 píxeles, y comprobamos a continuación si se ha cargado. En caso de no cargarse la imagen se muestra por consola un texto informativo. También creamos la ventana en la que se mostrará el resultado final.

logo = cv::imread("/home/ikarus/nombre.jpg", CV_LOAD_IMAGE_COLOR);

if (!logo.data)
{
    printf("No se ha cargado la imagen.");
}

cvNamedWindow("monocolor", 1);

En mi caso, como quiero añadir un logo a las imágenes capturadas por la Kinect, primero convierto el flujo de datos de Kinect a un objeto cv::Mat de tres canales para poder trabajar con él. Hay que hacer esta conversión debido a que la nube de puntos devuelta por Kinect incorpora, además de los colores por pixel, otra información como la distancia a la que se encuentra ese punto, obtenida mediante su sensor de infrarrojos. En mi caso, el objeto de tipo cv::Mat sobre el que expondremos el logo se llama original, como resultado de guardar en esta matriz los colores de los píxeles del fotograma i-esimo.

Lo que se debe hacer para incrustar el logo es crear una estructura de tipo rectángulo, que será nuestra región de interés sobre la que poner el logo. Contendrá un punto de inicio (par x-y),  y un tamaño (longitud en columnas y filas). La crearemos mediante la función cv::Rect(pos_x, pos_y, long_columnas, long_filas). Después, clonamos la imagen original (cv::Mat original) que mostraremos al final del todo con el logo. Obtenemos de la imagen original la región de interés (ROI). Hacemos lo mismo con la imagen clonada. Por último, utilizando la función cv::addWeighted(imagen1, peso_imagen_1, imagen2, peso_imagen_2, salida_imagen) hacemos la mezcla de ambas imágenes, guardando el resultado en la estructura que le indicamos al final (salida_roi).

cv::Rect roi = cv::Rect(490, 10, logo.cols, logo.rows);
cv::Mat salida = original.clone();
cv::Mat imageRoi = original(roi);
cv::Mat salida_roi = salida(roi);
cv::addWeighted(imageRoi, 1.0, logo, 0.3, 0.0, salida_roi);

Ahora, mostramos el resultado final.

cv::imshow("monocolor", salida);

Logo

Ros Hydro + Kinect + Ubuntu 12.04

Este post es un recordatorio para mi yo del futuro cuando quiera volver a instalar Ros y usar la Kinect sobre Ubuntu 12.04.

Para la instalación de Ros, nada mejor que seguir el manual del propio Ros:

http://wiki.ros.org/hydro/Installation/Ubuntu

Una vez instalado Ros, hay que instalar las bibliotecas Openni para poder hacer funcionar Kinect:

$ sudo apt-get install ros-hydro-openni-*

Ahora hay que quitar los módulos gspca porque, de lo contrario, no nos permitirá lanzar openni correctamente y dará fallos (por la terminal aparecerá mucho rojo, demasiado):

$ sudo modprobe -r gspca_kinect
$ sudo modprobe -r gspca_main

Ya es el momento de probar si funciona este tinglado. Primero ejecutamos Openni en una terminal para activar la Kinect y los topics.

$ roslaunch openni_launch openni.launch

Si no salen errores, desde otra terminal abrimos rviz.

$ rosrun rviz rviz

En rviz, para poder ver algo, hay que añadir los siguientes displays y configurarlos con estos topics:

  • Fixed Frame:
    • /camera_depth_optical_frame
    • /camera_depth_frame (para ver la imagen solapada con la distribución de puntos del sensor de infrarrojos).
  • Image:
    • /camera/rgb/image_color (esto nos mostrará en una ventanita la imagen a todo color de lo que esté capturando la cámara).
  • PointCloud2:
    • /camera/depth_registered/points (nos muestra la nube de puntos de los objetos que detecta el sensor de infrarrojos).

A la hora de crear un paquete, en la versión Hydro de Ros, la dependencia pcl de la versión Electric pasa a llamarse pcl_conversions y pcl_ros (yo añado ambas por si acaso). Además, la cabecera .h ya no es pcl/ros/conversions.h, sino que es pcl_conversions/pcl_conversions.h.

Rviz mostrando las capturas de Kinect.

Ejercicio coloreado puntos Kinect

Fuentes:

 


 

En el caso de que al configurar rviz no se muestren los puntos de profundidad de la imagen coloreados, es debido a que hay que configurar el driver de la Kinect. Para hacer esto abrimos una nueva terminal y ejecutamos la siguiente instrucción:

$ rosrun dynamic_reconfigure reconfigure_gui

O, en el caso de que el comando anterior no funcione, hay que ejecutar este otro (con Ubuntu 13.04 he tenido que usar este):

$ rosrun rqt_reconfigure rqt_reconfigure

Entonces, aparecerá una nueva ventana. En ella desplegamos el árbol de camera y después seleccionamos driver. Dentro de las opciones que se muestran marcamos la casilla depth_registration. En ese momento en rviz deberán aparecer los puntos de profundidad en la rejilla.

Configurar driver Kinect

 

SQL Server: Añadiendo el número de fila

Algunas veces me ha hecho falta poder filtrar registros por número de fila más que por otro campo existente en la tabla. Este método se basa en crear una tabla temporal con los registros de la consulta a realizar añadiendo una columna nueva con el número de fila, la cuál podremos utilizar en el segundo paso para filtrar los registros. Finalmente, eliminaremos la tabla temporal.

Mi consulta inicial es la siguiente:

SELECT [sequence]
FROM _smdba_._telmaste_
WHERE [lastmodified] BETWEEN '2012-06-07' AND '2012-06-08'
ORDER BY [sequence] ASC

Primer paso, modificamos la consulta inicial indicando sobre qué tabla temporal queremos volcar los resultados. Además, añadimos la columna que almacenará el número de la fila. La función IDENTITY() sólo puede ser utilizada con la cláusula INTO. Por tanto, si no la ponemos nos dará error.

SELECT IDENTITY(int, 1,1) AS numero_fila, [sequence]
INTO #temporal
FROM _smdba_._telmaste_
WHERE [lastmodified] BETWEEN '2012-06-07' AND '2012-06-08'
ORDER BY [sequence] ASC

Segundo paso, realizamos la consulta final sobre la tabla temporal.

SELECT *
FROM #temporal
WHERE numero_fila > 43000
ORDER BY numero_fila ASC

Tercer paso, eliminamos la tabla temporal.

DROP TABLE #temporal

Nota: Esto lo he realizado sobre un SQL Server 2000.

Concierto de Rammstein en el BEC

El viernes pasado (19 de Abril de 2013) fui al concierto de Rammstein que hubo en Barakaldo en el BEC (Bilbao Exhibition Center). Para mí fue mi primer concierto, nunca antes estuve en ningún otro y me pareció increíble el despliegue de luces y efectos que hubo en él. Además de la cantidad de altavoces que hubo. Aunque los efectos que más me gustaron fueron los de fuego. Desde donde estuve, que no era precisamente cerca del escenario, se podía notar el calor de las llamas.

Dejo un vídeo que grabé durante el concierto de la canción Sonne del disco Mutter, así como, unas imágenes que he sacado de otros vídeos que hice.