Tag Archives: Hipergalaxia

Solucionando problemas con las firmas GPG de los paquetes en GNU/Linux Ubuntu y Mint

Introducción

Después de una acción aún no determinada, posiblemente agregar un nuevo repositorio de paquetes al sistema operativo, empecé a obtener errores de firmas GPG como los siguientes durante la actualización de los índices de los paquetes en los repositorios con Aptitude.

W: GPG error: http://archive.ubuntu.com oneiric Release: The following signatures were invalid: BADSIG 40976EAF437D05B5 Ubuntu Archive Automatic Signing Key <ftpmaster@ubuntu.com>
W: GPG error: http://ppa.launchpad.net oneiric Release: The following signatures were invalid: BADSIG B9316A7BC7917B12 Launchpad chrislea
W: GPG error: http://ppa.launchpad.net oneiric Release: The following signatures were invalid: BADSIG B6C6326781C0BE11 Launchpad All you need for Ruby/Rails development on Ubuntu
W: GPG error: http://ppa.launchpad.net oneiric Release: The following signatures were invalid: BADSIG C2518248EEA14886 Launchpad VLC
W: A error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: http://ppa.launchpad.net oneiric Release: The following signatures were invalid: BADSIG C2518248EEA14886 Launchpad VLC

La solución

Para solucionar esta situación se siguieron los pasos mostrados a continuación.

Renombrar (mover o remover) las listas de índices de paquetes actualmente manejadas por el sistema operativo.

$ sudo mv /var/lib/apt/lists /var/lib/apt/lists.old

Recrear el directorio de almacenamiento de las listas de índices.

$ sudo mkdir -p /var/lib/apt/lists/partial

Limpiar los paquetes almacenados en el sistema de archivos local descargados durante procedimientos anteriores.

$ sudo apt-get clean

Solicitar nuevamente las listas de índices de los paquetes contenidos en los repositorios actualmente registrados en el sistema operativo

$ sudo apt-get update

Campos autonuméricos con SQLite3

Introducción

SQLite es un gestor de bases de datos pequeño y simple que se usa ampliamente como apoyo al software (aplicaciones de escritorio, navegadores web, etc.) y en sistemas embebidos como los teléfonos móviles (Android por ejemplo).

A continuación se muestra como crear campos autonuméricos en esta base de datos, es decir, campos cuyo valor es un número serial que es asignado automáticamente por el software.

Procedimiento

Crear la tabla con el campo autonumérico (code en este caso).

CREATE TABLE test (
code     INTEGER        PRIMARY KEY    AUTOINCREMENT,
name     VARCHAR(20)    UNIQUE,
value    FLOAT
);

Agregar datos a la tabla recién creada.

INSERT INTO test VALUES(NULL, 'demo1', 10.10);
INSERT INTO test VALUES(NULL, 'demo2', 20.20);
INSERT INTO test VALUES(NULL, 'demo3', 30.30);

Consultar los datos recién ingresados.

sqlite> select * from test;
    1|demo1|10.1
    2|demo2|20.2
    3|demo3|30.3

Consultar el valor del último campo autonumérico ingresado durante la sesión.

SELECT last_insert_rowid();
    3

Enlaces

Permisos de archivos/directorios incorrectos para el servidor de páginas en GNU/Linux

Introducción

El problema mas común que impide que se pueda acceder correctamente a un sitio o aplicación web que se está instalando o desarrollando es que los archivos y directorios no cuenten con los permisos de acceso apropiados para que el servidor de páginas (Apache por ejemplo) pueda accederlos correctamente.  En estos casos se obtiene un mensaje de error similar al  mostrado a continuación.

failed to open stream: Permission denied in /ruta/al/proyecto/index.php on line xx

La solución

En términos generales, los directorios deben contar con permisos 755 (drwxr-xr-x) y los archivos -como .php- 644 (-rw-r–r–).  Esta modificación puede realizarse de manera recursiva aprovechando la flexibilidad del comando find de la siguiente manera.

$ find /ruta/al/proyecto -type d -exec chmod 755 {} \;
$ find /ruta/al/proyecto -type f -exec chmod 644 {} \;

Inclusive es posible establecer filtros a los nombres de los recursos actualizados para mayor precisión en el cambio.

$ find /ruta/al/proyecto -type f -name '*.php' -exec chmod 644 {} \;

Invalid command 'RewriteEngine' con Apache2

Introducción

Intentando utilizar un software web que incluía un .htaccess y este se aprovechaba de la funcionalidad del RewriteEngine de Apache2, obtenía siempre el siguiente mensaje de error.

Invalid command 'RewriteEngine', perhaps misspelled or defined by a module not included in the server configuration

Solución

Activar el módulo del RewriteEngine de Apache2.

$ sudo a2enmod rewrite

Reiniciar Apache2 para que tenga en cuenta al módulo recién activado.

$ sudo service apache2 restart

Instalando Unity 5.0 en GNU/Linux Ubuntu 11.10

Introducción

Unity 5.0 es actualmente la última versión del ambiente de escritorio desarrollado por Canonical para Ubuntu su distribución de GNU/Linux.  Está versión que trae mejoras en su desempeño, se incluirá con la versión 12.04 ("Precise Pangolin") a liberarse en el mes de abril del 2012.

A continuación se describe el procedimiento necesario para instalar y desinstalar (no se ha probado aún) la versión mas reciente de Unity en Ubuntu 11.10.

Instalación

$ sudo add-apt-repository ppa:unity-team/ppa
$ sudo apt-get update && sudo apt-get dist-upgrade

*Anotación* Si desea instalar los paquetes mas recientes que aún no cuentan con las pruebas de aceptación utilice el repositorio ppa:unity-team/staging.

Desinstalación

$ sudo apt-get install ppa-purge
$ sudo ppa-purge ppa:unity-team/ppa

Detectando movimiento con GSVideo y Processing

Introducción

De manera análoga a como se realizó inicialmente con OpenCV, se realizó el proceso de detección de movimiento básico utilizando Processing y la librería de GSVideo instalada hace poco.  Esta librería se especializa en la captura, grabación y reproducción del video mas que en su procesamiento así que la manipulación de las imágenes se realiza manualmente con las facilidades que provee el lenguaje.

En términos generales el procedimiento se basa en capturar el video proveniente de la cámara web a través de una instancia de la clase GSCapture provista por la librería GSVideo.  Cada una de las imágenes obtenidas es comparada con la imagen inmediatamente anterior.  De cada uno de sus píxeles se toma el color en forma de tripleta RGB y se determina su cantidad de variación utilizando la fórmula de distancia (función dist en Processing).  De esta manera se determina si en ese punto específico sucedió movimiento o no y es traducido a un píxel de color blano o negro respectivamente.

Screenshot

Imagen de movmiento sobre el objetivo

Imagen de movmiento sobre el objetivo


Enlaces

Instalando GSVideo en Processing bajo GNU/Linux

Introducción

GSVideo es una librería para Processing desarrollada por Andrés Colubri y basada en GStreamer.  Esta librería permite reproducir videos (incluyendo a la cámara web), capturar imágenes y realizar grabaciones.  Su API sigue los lineamientos de la librería nativa (processing.video.*) la cual por estar basada en Apple QuickTime no se encuentra disponible en GNU/Linux.

Instalación

La instalación de la distribución binaria es muy simple y se describe a continuación.

Descargar la versión mas reciente de la librería desde la siguiente ubicación.

http://sourceforge.net/projects/gsvideo/files/gsvideo/

En este caso se obtuvo el archivo GSVideo-1.0.0-linux.zip.

Descomprimir el paqute con la distribución de la librería.

$ unzip GSVideo-1.0.0-linux.zip

Reubicar la librería en el lugar apropiado del sketchbook.

$ mv GSVideo ~/sketchbook/libraries/

Dependencias

Como se mencionó inicialmente esta librería depende de GStreamer para su funcionamiento.  Utilizando GNU/Linux Mint 12 no fue necesario instalar ningún paquete adicional para trabajar con la librería.

$ sudo aptitude search gstream | grep "^i"

i   bluez-gstreamer                 – Bluetooth GStreamer support               
i   gir1.2-gstreamer-0.10           – Description: GObject introspection data fo
i   gstreamer0.10-alsa              – GStreamer plugin for ALSA                 
i   gstreamer0.10-ffmpeg            – FFmpeg plugin for GStreamer               
i   gstreamer0.10-fluendo-mp3       – Fluendo mp3 decoder GStreamer plugin      
i   gstreamer0.10-gconf             – GStreamer plugin for getting the sink/sour
i   gstreamer0.10-nice              – ICE library (GStreamer plugin)            
i   gstreamer0.10-pitfdll           – GStreamer plugin for using MS Windows bina
i   gstreamer0.10-plugins-bad       – GStreamer plugins from the "bad" set      
i   gstreamer0.10-plugins-bad-multi – GStreamer plugins from the "bad" set (Mult
i   gstreamer0.10-plugins-base      – GStreamer plugins from the "base" set     
i   gstreamer0.10-plugins-base-apps – GStreamer helper programs from the "base"
i   gstreamer0.10-plugins-good      – GStreamer plugins from the "good" set     
i   gstreamer0.10-plugins-ugly      – GStreamer plugins from the "ugly" set     
i   gstreamer0.10-pulseaudio        – GStreamer plugin for PulseAudio           
i   gstreamer0.10-tools             – Tools for use with GStreamer              
i   gstreamer0.10-x                 – GStreamer plugins for X11 and Pango       
i   libgstreamer-plugins-base0.10-0 – GStreamer libraries from the "base" set   
i   libgstreamer0.10-0              – Core GStreamer libraries and elements

Demostración

El siguiente código se basa en el ejemplo GettingStartedCaptureLinux incluído en la distribución de la librería.

// Import the GSVideo library classes
import codeanticode.gsvideo.*;
// GSVideo capture object reference
GSCapture cam;
void setup()
{
  size(640, 480);
  // Create the GSVideo capture object with the capture's resolution
  cam = new GSCapture(this, 640, 480);
  // Begin the video capture process
  cam.start();
  // Retrieve the video resolutions available
  println("Supported video resolutions: ");
  int[][] res = cam.resolutions();
  for (int i = 0; i < res.length; i++)
  {
    println(res[i][0] + "x" + res[i][1]);
  }
  println();
  // Retrieve the video framerates available
  println("Supported video framerates: ");
  String[] fps = cam.framerates();
  for (int i = 0; i < fps.length; i++)
  {
    println(fps[i]);
  }
}
void stop()
{
  // Stop the GSVideo webcam capture
  cam.stop();
  // Stop the sketch
  this.stop();
}
void draw()
{
  // Check if there is a capture device available
  if (cam.available() == true)
  {
    // In this case, read an image from it
    cam.read();
    // Display it on the window
    image(cam, 0, 0);
  }
}

Enlaces

Detectando movimiento con OpenCV y Processing

Introducción

Una de las características que quería aprender a implementar con OpenCV era la detección de movimiento, esto me permitirá implementar formas de interacción interesantes (y bastante simples de generar) entre el usuario y el sketch a través de la cámara web.

En pocas palabras, la técnica para detectar movimiento que se describe a continuación se basa en generar una imagen monocromática con los píxeles que han cambiado entre dos cuadros del video.  Para hacer esto se siguen los pasos mostrados a continuación.

  1. Obtener una nueva imagen de la cámara web
  2. Invertir la imagen horizontalmente (opcional)
  3. Calcular la diferencia entre la imagen recién obtenida y la almacenada en memoria (recordada)
  4. Procesar la imagen para facilitar su manejo: convertirla a escala de grises, suavizar la imagen y reducir el ruido eliminando los valores demasiado altos o bajos.
  5. Mostrar la imagen de movimiento (opcional)
  6. Recordar la imagen actual para ser procesada nuevamente en la siguiente iteración

opencv.read();

opencv.flip(OpenCV.FLIP_HORIZONTAL);

opencv.absDiff();

opencv.convert(OpenCV.GRAY);

opencv.blur(OpenCV.BLUR, 3);

opencv.threshold(20);

image(opencv.image(), 0, 0);

opencv.remember(OpenCV.SOURCE, OpenCV.FLIP_HORIZONTAL); 

Para verificar si ha sucedido movimiento en una determinada área de la imagen se debe verificar si los píxeles que pertenecen a esa área se encuentran blancos (si hubo) o no.  Esta información se obtiene utilizando el método get(int x, int y) del objeto PImage el cual retorna el color del píxel seleccionado.  Por facilidad se recomienda que se obtenga el brillo (brightness(color)) de este píxel para su comparación.

El siguiente código revisa un área cuadrada de píxeles en búsqueda de movimiento en esa zona.

for(int px=x; px<x+size; px++)  
    for(int py=y; py<y+size; py++)     
        if (px < width && px > 0 && py < height && py > 0)       
            if (brightness(mImage.get(px, py)) > 127)
                count ++;

Screenshot

Imagen de movmiento sobre el objetivo (modo buffer)

Imagen de movmiento sobre el objetivo (modo buffer)

 

Enlaces

Poniendo sombreros a las personas con OpenCV y Processing

Introducción

Como una versión un poco mas elaborada de la publicación anterior he preparado este sketch que toma el flujo de video proveniente de la cámara web,  encuentra en él los rostros de las personas y les pone un sombrero.  Se incluyen diferentes sombreros que pueden cambiarse mediante el teclado.

q – terminar el sketch
a – mostrar/ocultar el rectángulo rojo alrededor de cada cara encontrada
s – mostrar/ocultar la máscara sobre cada cara encontrada
z/x – alternar entre las imágenes de máscaras disponibles

Screenshots

Demostración con varias personas en la misma imagen

Demostración con varias personas en la misma imagen

Demostración con la foto de un rostro

Demostración con la foto de un rostro

Agradecimientos para Martha, Diego y Jennifer Connerlly por participar como modelos para las fotos del artículo.

Acerca de la ubicación de los rostros

Hasta el momento el perfil que mejores resultados me ha dado para ubicar los rostros de las personas ha sido OpenCV.CASCADE_FRONTALFACE_ALT_TREE (haarcascade_frontalface_alt_tree.xml).  Este encuentra los rostros con el menor número de errores (identificación equivocada de un objeto inanimado como si fuera un rostro), sin embargo parece tener poca tolerancia a las variaciones de posición del rostro de las personas, si ellas agachan o rotan un poco la cara probablemente ya no serán renocidas.  Un trabajo a futuro consistirá en encontrar como mejorar estos resultados de la ubicación de rostros.

Estos son los perfiles de reconocimiento disponibles a través de OpenCV según la instalación que se realizó de la librería.

Los siguientes perfiles se encuentran disponibles como constantes asociadas a la clase OpenCV de Processing.

  public static final String CASCADE_FRONTALFACE_ALT_TREE
  public static final String CASCADE_FRONTALFACE_ALT
  public static final String CASCADE_FRONTALFACE_ALT2
  public static final String CASCADE_FRONTALFACE_DEFAULT
  public static final String CASCADE_PROFILEFACE
  public static final String CASCADE_FULLBODY
  public static final String CASCADE_LOWERBODY
  public static final String CASCADE_UPPERBODY

A continuación se listan todos los archivos XML de los perfiles de reconocimiento que también pueden ser utilizados directamente en Processing.

  haarcascade_eye_tree_eyeglasses.xml   
  haarcascade_frontalface_default.xml  
  haarcascade_mcs_eyepair_small.xml  
  haarcascade_mcs_upperbody.xml
  haarcascade_eye.xml                   
  haarcascade_fullbody.xml             
  haarcascade_mcs_lefteye.xml        
  haarcascade_profileface.xml
  haarcascade_frontalface_alt2.xml      
  haarcascade_lefteye_2splits.xml      
  haarcascade_mcs_mouth.xml          
  haarcascade_righteye_2splits.xml
  haarcascade_frontalface_alt_tree.xml  
  haarcascade_lowerbody.xml            
  haarcascade_mcs_nose.xml           
  haarcascade_upperbody.xml
  haarcascade_frontalface_alt.xml       
  haarcascade_mcs_eyepair_big.xml      
  haarcascade_mcs_righteye.xml 

Enlaces