martes, 9 de octubre de 2012

Compilación de Opencv 2.4 para un sistema embebido con Linux (Openwrt)

En la siguiente guía se desarrollan los pasos necesarios para la compilación de la librería Opencv versión 2.4 para un sistema embebido. El sistema objetivo contiene el procesador JZ4725 (núcleo Xburst). Por otro lado, el sistema anfitrión es operado bajo Debian Squeeze (6.0.6).

Los detalles referentes al toolchain utilizado no son revisados, se asume que ya está funcionando y que se conoce la ruta al compilador. Este último  probablemente tenga la forma:

mipsel-openwrt-linux-uclibc-gcc

o algo parecido dependiendo del sistema objetivo y del toolchain utilizado, lo más relevante en la línea anterior es que hace referencia al compilador de código C para una arquitectura diferente a la de nuestro sistema (probablemente X86 o x86-64) [1].

Dependencias

Para compilar Opencv sin errores, se instaló la versión 2.8 de Cmake desde el repositorio backports de Debian, para tal fin, se ejecuta  lo siguiente:

$ apt-get -t squeeze-backports install cmake

Se asume que el repositorio backports de Debian es funcional en el sistema anfitrión, de lo contrario es necesario agregar dicho repositorio[2].

El código fuente de Opencv puede obtenerse de varias formas, aquí se utiliza git para clonar el repositorio de la siguiente manera:

$ git clone git://code.opencv.org/opencv.git

También es posible descargar solamente la versión que necesitamos (Opencv 2.4.0), sin embargo, el repositorio git nos permite acceder a otras versiones, por ejemplo: 2.2, 2.3 y 2.4.2. Para acceder a estas   se puede crear una nueva rama (branch) de la siguiente forma:


$ git checkout version

$ git checkout -b nombre_nueva_rama

Existen otras dependencias para la correcta compilación de Opencv, en Debian se utiliza la siguiente linea:


$ sudo apt-get build-dep  opencv

Procedimiento

Una vez  estén completas las dependencias de compilación, se crea una carpeta, que para este caso se ubica dentro  del directorio opencv (el nombre puede variar según el método de descarga). La operación anterior se realiza de la siguiente manera


$ mkdir buildcv;cd buildcv

En el directorio buildcv se procede a compilar Opencv, para tal fin es necesario pasar varios argumentos a cmake quedando la linea de la siguiente manera


$ cmake -D CMAKE_TOOLCHAIN_FILE=toolchain.cmake -D  CMAKE_INSTALL_PREFIX=/ruta/a/la/carpeta/de/instalacion -D WITH_1394=OFF -D WITH_FFMPEG=OFF -D WITH_GSTREAMER=OFF -D WITH_GTK=OFF -D WITH_XINE=OFF -D WITH_XIMEA=OFF -D WITH_V4L=OFF   .. 

Donde toolchain.cmake es un archivo de configuración para cmake que debe estar contenido en la carpeta buildcv y el cual tiene el siguiente contenido

$ vim toolchain.cmake

#######################################################
## Archivo de configuración para realizar la compilación de Opencv   ##
#######################################################
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR mips)
set(CMAKE_C_COMPILER mipsel-openwrt-linux-uclibc-gcc)
set(CMAKE_CXX_COMPILER mipsel-openwrt-linux-uclibc-g++)
#Las dos sentencias anteriores proporcionan información de los compiladores 
#cruzados.
set(CMAKE_FIND_ROOT_PATH /ruta/al/toolchain/trunk)
# La sentencia anterior debe indicar la ruta del toolchain.
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
#La sentencia anterior indica que cmake no buscará programas en el sistema host.
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# Las dos sentencias anteriores indican que las librerías y los headers se buscan en 
#target(toolchain).
set(WITH_FFMPEG CACHE STRING OFF FORCE)
set(WITH_1394 CACHE STRING OFF FORCE)
set(WITH_GSTREAMER CACHE STRING OFF FORCE)
set(WITH_GTK CACHE STRING OFF FORCE)
set(WITH_XINE CACHE STRING OFF FORCE)
set(WITH_XIMEA CACHE STRING OFF FORCE)
set(WITH_V4L CACHE STRING OFF FORCE)
set(BUILD_PYTHON_SUPPORT CACHE STRING OFF FORCE)
# las últimas ocho sentencias eliminan algunos plugins que no son de utilidad para un sistema 
# embebido (para los propósitos del autor).

Al ejecutar la sentencias con cmake se realiza un resumen de lo que va a ser compilado, si no existe ningún error el siguiente paso es

$ make -j3

Donde -j3 indica en número de procesos que se van a utilizar para la compilación. Después de aproximadamente 20 minutos esta finalizará (dependiendo del procesador). Seguidamente se tiene que instalar Opencv en el directorio que se paso a cmake como argumento
(-D CMAKE_INSTALL_PREFIX=/ruta/a/la/carpeta/de/instalacion

$ make install

La orden anterior crea los directorios bin/ include/ /lib/ share/ en  la carpeta ruta/a/la/carpeta/de/instalacion . De los directorios anteriores es necesario copiar al sistema embebido include/ y lib/ en los directorios  /usr/include y /usr/lib , para tal fin se utiliza el comando tar a través de ssh resultando en:

$ tar -cf - ruta/a/la/carpeta/de/instalacion/include | ssh user@host tar -xf -/usr/include
y
$ tar -cf - ruta/a/la/carpeta/de/instalacion/lib | ssh user@host tar -xf -/usr/lib

Es necesario copiar los archivos al sistema embebido de la forma anterior debido a la existencia de  enlaces simbólicos que son parte del funcionamiento de las librerías de Opencv. Con este último paso el sistema embebido tiene la capacidad de manejar las librerías de Opencv.


Comprobar el funcionamiento de Opencv en el sistema embebido

Después de tener las librerías de Opencv compiladas para el sistema objetivo es oportuno comprobar su correcto funcionamiento. Primeramente desde el sistema host  creamos una variable de entorno que nos permite utilizar el programa pkg-config. De esta forma podemos llamar las librerías de Opencv y compilar los programas de una forma sencilla. Para lograr esto se ejecuta lo siguiente desde un terminal o también se puede  colocar en le archivo .bashrc:

$PKG_CONFIG_PATH=ruta/a/la/carpeta/de/instalacion/lib/pkgconfig:${PKG_CONFIG_PATH}

$ export PKG_CONFIG_PATH

Para comprobar el funcionamiento de pkg-config ejecutamos lo siguiente(se deben mostrar las rutas de las librerías)

$ pkg-config --cflags opencv

$ pkg-config --libs opencv

Es posible que en el sistema anfitrión (Debian) exista una compilación de Opencv, y que a su vez esta utilice  el programa  pkg-config, en tal caso se puede cambiar el nombre al que responden las librerías de Opencv en el sistema embebido. Para realizar lo anterior se cambia el nombre del siguiente archivo
ruta/a/la/carpeta/de/instalacion/lib/pkgconfig/opencv.pc   y el campo Name: que está dentro de este. El nuevo nombre del archivo podría ser opencvembedded.pc y para el campo Name:OpenCVembedded. quedando la ejecución del comando pkg-config:

$ pkg-config --cflags opencvembedded

$ pkg-config --libs opencvembedded

Finalmente, para compilar un programa de ejemplo se ejecuta la siguiente linea:

mipsel-openwrt-linux-gcc  `pkg-config --cflags --libs opencvembedded` -o redimension redimension.cpp   

Donde redimension.cpp es un archivo con código C que implementa las librerías de Opencv para cambiar el tamaño de una imagen (.jpg), el modo de uso se pude encontrar en [3].


#include <iostream>
#include "cv.h"
#include "highgui.h"

using namespace std;

int main( int argc, char** argv )
{
// Create an IplImage object *image 
IplImage *source = cvLoadImage( argv[1]);
// Here we retrieve a percentage value to a integer
int percent = atoi(argv[3]);

// declare a destination IplImage object with correct size, depth and channels
 IplImage *destination = cvCreateImage
( cvSize((int)((source->width*percent)/100) , (int)((source->height*percent)/100) ),
                                     source->depth, source->nChannels );

//use cvResize to resize source to a destination image
cvResize(source, destination);

// save image with a name supplied with a second argument
cvSaveImage( argv[2], destination );
return 0;
}

Códigos útiles



Para que guardar un log y que en terminal solo muestre lineas que contenga la palabra error o warning. Util en el paso de compilación.


ionice -c 3 nice -n 20 make -j 3 V=99 CONFIG_DEBUG_SECTION_MISMATCH=y 2>&1 | tee build.log | egrep -i '(warn|error)'

Borrado de archivos  excepto uno (toolchain.cmake). Utila cuando se producen errores en la sentencia de cmake -D ..., luego elimina archivos que corresponden a una mala configuración y deja el archivo de toolchain.cmake


for a in `ls | grep -v toolchain.cmake`; do rm -fr $a; done                                                                                                                   

No hay comentarios:

Publicar un comentario