DESCRIPCIÓN

En esta aplicación se construyo un prototipo de un sistema de realidad aumentada para mostrar información sobre componentes químicos en un ambiente de cabina de extracción implementada en un dispositivo Android.

OBJETIVO

Crear un prototipo de aplicación de realidad aumentada mediante un dispositivo móvil Android, para mostrar información sobre componentes químicos en un ambiente de cabina de extracción.

SOFTWARE NECESARIO

HARDWARE NECESARIO

  • Samsung Galaxy Note (u otro móvil con Android 2.1 o superior, que cuente con GPU integrado y procesador de más de 600MHz)

DESARROLLO

Un buen tutorial para comenzar a usar D’Fusion Studio es: https://community.t-immersion.com/getting-started. Algunos ejemplos de utilidad para entender el funcionamiento de D’Fusion Studio se pueden conseguir en: https://community.t-immersion.com/samples

Instalación de los entornos de desarrollo

El primer programa a instalar es D’Fusion 3.20. Para descargar este software es necesario registrarse de manera gratuita en la página de total immersion (http://www.t-immersion.com/). Después de descargado se debe seguir las instrucciones de instalación proporcionadas por el instalador.

El segundo componente a instalar es el SDK de Android http://developer.android.com/sdk/index.html, que permite desarrollar aplicaciones para Android. Para Windows existe un instalador con extensión .exe que es muy sencillo de instalar. Para que la instalación sea exitosa es necesario tener el kit de desarrollo de java 1.6 (JDK 1.6).

Después de instalar el SDK, es necesario descargar en el SDK Manager el SDK Platform para la versión 2.1. Para esto, se debe abrir el SDK Manager desde el menú inicio, luego se debe seleccionar los siguienes componentes dentro de la carpeta Android 2.1 (API 7):

  • SDK Platform
  • Samples for SDK (Opcional)
  • Google APIs

Después de esto se debe instalar la versión 3.6.2 de Eclipse.

Una vez instalado Eclipse, se debe instalar el ADT Plugin para Eclipse. Las instrucciones detalladas de la instalación se pueden encontrar en: http://developer.android.com/sdk/eclipse-adt.html

Explicación de la implementación en D’Fusion

Después de crear un nuevo proyecto se debe configurar el proyecto de manera adecuada para que luego pueda correrse en un dispositivo móvil.

Al configurar la cámara de la escena en D’fusion, se debe dar click en “Alternative Platform” y específicar configuraciones adecuadas para las plataformas no PC en las que se desea correr la aplicación. Una manera sencilla de hacer esto es utilizando las plantillas que vienen con D’Fusion y se pueden encontrar en la carpeta de instalación. El resultado se puede observar en la siguiente imagen:

El código del archivo “cameraCalib_android_640x480.xml” se modificó para que sea adecuado para el celular Samsung Galaxy Note, dado que este tiene una cámara HD y la configuración estándar no considera este hecho.

<?xml version="1.0" standalone="yes" ?>
<CAMERABASE>
	<CAMERABASE>
		<COMMENTS>android_640x480</COMMENTS>
		<MODELE>OPENCV_0</MODELE>
		<MAXX>800</MAXX>
		<MAXY>480</MAXY>
		<PX>400</PX>
		<PY>240</PY>
		<FX>660</FX>
		<FY>660</FY>
		<A1>0</A1>
		<A2>0</A2>
		<P1>0</P1>
		<P2>0</P2>
		<DEDISTORTION>true</DEDISTORTION>
	</CAMERABASE>
</CAMERABASE>

En el componente tipo videocapture también se debe hacer algo similar a lo que se hizo en el paso anterior.

Aquí también se modifico el archivo “videoConfig_android_backcam_640x480_15fps.xml”, el resultado del archivo se muestra a continuación:

<?xml version="1.0" standalone="yes" ?>
<TI>
	<VIDEOCAP>
		<COMMENTS>android_backcam_640x480_15fps</COMMENTS>
		<VIDEO_CAPTURE_FILE></VIDEO_CAPTURE_FILE>
		<VIDEO_CAPTURE_NUM_DRIVER>0</VIDEO_CAPTURE_NUM_DRIVER>
		<VIDEO_CAPTURE_PIXEL_FORMAT>NV12</VIDEO_CAPTURE_PIXEL_FORMAT>	
		<VIDEO_CAPTURE_WIDTH>800</VIDEO_CAPTURE_WIDTH>	
		<VIDEO_CAPTURE_HEIGHT>480</VIDEO_CAPTURE_HEIGHT>
		<VIDEO_CAPTURE_DELAY>1</VIDEO_CAPTURE_DELAY>
		<VIDEO_CAPTURE_RATE>15.000000</VIDEO_CAPTURE_RATE>
		<VIDEO_CAPTURE_NB_FRAME_BUFFERS>4</VIDEO_CAPTURE_NB_FRAME_BUFFERS>
		<VIDEO_CAPTURE_INTERLACED>0</VIDEO_CAPTURE_INTERLACED>
		<VIDEO_CAPTURE_INVERTED>1</VIDEO_CAPTURE_INVERTED>
		<VIDEO_CAPTURE_PRIORITY>3</VIDEO_CAPTURE_PRIORITY>
		<VIDEO_CAPTURE_TYPE>0</VIDEO_CAPTURE_TYPE>
		<VIDEO_CAPTURE_NAME></VIDEO_CAPTURE_NAME>
		<VIDEO_CAPTURE_CPU>0</VIDEO_CAPTURE_CPU>
		<VIDEO_CAPTURE_PAUSE>1</VIDEO_CAPTURE_PAUSE>
		<VIDEO_CAPTURE_DEINTERLACE>1</VIDEO_CAPTURE_DEINTERLACE>
		<VIDEO_CAPTURE_SHADER>0</VIDEO_CAPTURE_SHADER>
		<VIDEO_CAPTURE_FRIENDLY_NAME>back</VIDEO_CAPTURE_FRIENDLY_NAME>
		<VIDEO_CAPTURE_DEBUG>0</VIDEO_CAPTURE_DEBUG>
		<VIDEO_CAPTURE_RATE_IS_DYNAMIC>true</VIDEO_CAPTURE_RATE_IS_DYNAMIC>
		<VIDEO_CAPTURE_RESYNCHRO_PERIOD>0</VIDEO_CAPTURE_RESYNCHRO_PERIOD>
		<VIDEO_CAPTURE_STEADY_STATE_MARGIN>0.330000</VIDEO_CAPTURE_STEADY_STATE_MARGIN>
		<VIDEO_CAPTURE_TIMECODE_REINIT_PERIOD>0.500000</VIDEO_CAPTURE_TIMECODE_REINIT_PERIOD>
	</VIDEOCAP>
</TI>

Para hacer el seguimiento de los marcadores en la ejecución del programa, se requiere hacer un pre-procesamiento inicial. Para esto se debe abrir la herramienta de Computer Vision de D’Fusion, esto se hace dando clic en Tools y luego en Computer Vision.

Para que el algoritmo de seguimiento funcione en dispositivos móviles, se debe cambiar el modo a Lite, esto se hace dando clic en Mode y luego en Lite.

Para mejores resultados en el reconocimiento, es buena idea utilizar la misma cámara dispositivo para tomar las imágenes que luego se tratarán de identificar, por ello se tomó fotos a los marcadores con la cámara del celular en resolución de 800×480, y se recortó los pedazos que no correspondían a las imágenes. Las imágenes recortadas se pueden descargar del siguiente archivo:

01_marcadores.zip

En la pestaña “Scenario Manager”, en la sección “Target” se debe crear los 3 objetos que se pretenden seguir presionando el botón “Create”.

En la otra sección también llamada “Target”, se debe seleccionar el tipo (Type) “Plane” y dar un tamaño que represente la medida del objeto en el mundo real. En este caso el objeto impreso es de tamaño 5 cm x 3cm.

En la sección “Keyframes” se debe importar las imágenes. Esto se hace presionando el botón “Image(s)” y cargando las correspondientes al marcador que se desea seguir. Finalmente se debe presionar el botón “Generate Classifiers”. El proceso se debe repetir por cada marcador que contenga el sistema.

El código para realizar el seguimiento de los objetos y mostrar la información de los componentes se muestra a continuación, este código se debe agregar como script a la escena:

-- GLOBAL VARIABLES
-- tracking statuts: if 1 : tracking, if 0 : no tracking
gtrackingStatus = 0
-- get the keyframe index from a tracked object with auto-initialization
gtrackingKeyFrameIndex = -1
-- scene
local scene = getCurrentScene()
-- get the virtual camera, will be used to send to the MLT
local camera = Camera(scene:getCurrentCamera())
-- get the videocapture, will be used to send to the MLT
local videoCapture_live = VideoCapture(scene:getObjectByName("vidCap"))
-- Tracking
local MLTPlugin = getMLTPluginManager()
-- Error status
local errorStatus = eOk
-- tracking index : the index of the tracker.xml (because we can open more than 1 tracking.xml file).
local trackingIndex = -1
-- the fps of the Tracking engine
local trackingRate = 0
-- vector to put the tracking position
local trackingPosition = Vector3()
local trackingPosition1 = Vector3()
local trackingPosition2 = Vector3()
-- quaternion to put the tracking orientation
local trackingOrientation = Quaternion()
local trackingOrientation1 = Quaternion()
local trackingOrientation2 = Quaternion()
-- 3D object receiving tracking pose
local trackingObject = Object3D(scene:getObjectByName("ref"))
local trackingObject1 = Object3D(scene:getObjectByName("ref1"))
local trackingObject2 = Object3D(scene:getObjectByName("ref2"))
-- object index from the tracking scenario (0 : first object, 1 : second object...) (this is the index in the "Objects" panel of the CV GUI)
local trackingObjectIndex = 0
local trackingObjectIndex1 = 1
local trackingObjectIndex2 = 2
-- textos...
local title_hf = Text2D(scene:getObjectByName("title_hf"))
local text = Text2D(scene:getObjectByName("text"))
local text_visible = false
title_hf:setVisible(false)
text:setVisible(false)
-- this is how to start a tracking. the function needs the path to the tracker.xml file, the videocapture id and the camera object.
errorStatus, trackingIndex = MLTPlugin:startTracking("tracker/tracker.xml", videoCapture_live:getVidCapID(), camera)
-- if the tracking has correctly started, we can proceed to an infinite loop
if errorStatus == eOk then
repeat 
errorStatus, gtrackingStatus = MLTPlugin:getTargetStatus(trackingIndex, trackingObjectIndex) 
errorStatus, gtrackingKeyFrameIndex = MLTPlugin:getRecognizedKeyFrameIndex(trackingIndex, trackingObjectIndex)
-- if our object is detected...
if (gtrackingStatus == 1) then
--...we can get the position and set it to the "father" object
MLTPlugin:getTargetPos(trackingIndex, trackingObjectIndex, trackingPosition, trackingOrientation)
--trackingObject:setPosition(trackingPosition, camera)
trackingObject:setPosition(trackingPosition:getX(), trackingPosition:getY(), 0)
-- we change the visibility of the main "father" object
if not trackingObject:getVisible() then 
trackingObject:setVisible(true) 
title_hf:setText("ÁCIDO CLORHÍDRICO")
text:setText("RIESGOS:\n-Causa quemaduras\n" ..
"-Irritante para el sistema respiratorio\n" ..
"-Inhalación: irritación, edema y corrosión\n" .. 
"del sistema respiratorio\n" ..
"QUE HACER EN CASO DE EXPOSICIÓN:\n" ..
"-En caso de contacto con los ojos, enjuagar\n" .. 
"inmediatamente y buscar ayuda médica\n"..
"-En caso de accidente buscar ayuda\n" .. 
"médica inmediatamente\n" ..
"DESCRIPCIÓN:\n" ..
"-Es muy corrosivo y ácido. Se emplea comúnmente\n" .. 
"como reactivo químico y se trata de un ácido \n" ..
"fuerte que se disocia completamente en \n" ..
"disolución acuosa.")
text_visible = true
end
-- if the tracking is lost
else
-- we change the visibility of the main "father" object
if trackingObject:getVisible() then 
trackingObject:setVisible(false)
text_visible = false 
end
end
errorStatus, gtrackingStatus1 = MLTPlugin:getTargetStatus(trackingIndex, trackingObjectIndex1) 
errorStatus, gtrackingKeyFrameIndex1 = MLTPlugin:getRecognizedKeyFrameIndex(trackingIndex, trackingObjectIndex1)
-- if our object is detected...
if (gtrackingStatus1 == 1) then
--...we can get the position and set it to the "father" object
MLTPlugin:getTargetPos(trackingIndex, trackingObjectIndex1, trackingPosition1, trackingOrientation1)
--trackingObject1:setPosition(trackingPosition1, camera)
trackingObject1:setPosition(trackingPosition1:getX(), trackingPosition1:getY(), 0)
-- we change the visibility of the main "father" object
if not trackingObject1:getVisible() then 
trackingObject1:setVisible(true) 
title_hf:setText("ÁCIDO FLUORHÍDRICO")
text:setText("RIESGOS:\n" ..
"-Muy toxico por inhalación, en contacto por la \n" ..
"piel o si es ingerido.\n" ..
"-Causa quemaduras severas\n" ..
"QUE HACER EN CASO DE EXPOSICIÓN:\n" ..
"-En caso de contacto con los ojos, enjuagar \n" ..
"inmediatamente y buscar ayuda médica\n" ..
"-En caso de accidente buscar ayuda médica \n" ..
"inmediatamente\n" ..
"ELEMENTOS NECESARIOS DE TRABAJO:\n" ..
"-Usar traje y guantes de protección\n" ..
"DESCRIPCIÓN:\n" ..
"Compuesto químico formado por hidrógeno y flúor\n" ..
"(HF). No debe ponerse en contacto con elementos\n" ..
"de vidrio ya que puede corroerlo, por esto se \n" ..
"manipula utilizando material de plástico.")
text_visible = true
end
-- if the tracking is lost
else
-- we change the visibility of the main "father" object
if trackingObject1:getVisible() then 
trackingObject1:setVisible(false)
text_visible = false
end
end 
errorStatus, gtrackingStatus2 = MLTPlugin:getTargetStatus(trackingIndex, trackingObjectIndex2) 
errorStatus, gtrackingKeyFrameIndex2 = MLTPlugin:getRecognizedKeyFrameIndex(trackingIndex, trackingObjectIndex2)
-- if our object is detected...
if (gtrackingStatus2 == 1) then
--...we can get the position and set it to the "father" object
MLTPlugin:getTargetPos(trackingIndex, trackingObjectIndex2, trackingPosition2, trackingOrientation2)
--trackingObject2:setPosition(trackingPosition2, camera)
trackingObject2:setPosition(trackingPosition2:getX(), trackingPosition2:getY(), 0)
-- we change the visibility of the main "father" object
if not trackingObject2:getVisible() then 
trackingObject2:setVisible(true) 
title_hf:setText("AMONÍACO")
text:setText("RIESGOS:\n" ..
"-Ingestión: Síntomas incluyen náusea y \n" ..
"vómitos; daño a los labios, boca y esófago.\n" ..
"-Inhalación: Los vapores son extremadamente \n" ..
"irritantes y corrosivos.\n" ..
"-Piel: Soluciones concentradas pueden producir\n" ..
"quemaduras severas y necrosis.\n" ..
"-Ojos: Puede causar daños permanentes, incluso \n" ..
"en cantidades pequeñas")
text_visible = true
end
-- if the tracking is lost
else
-- we change the visibility of the main "father" object
if trackingObject2:getVisible() then 
trackingObject2:setVisible(false)
text_visible = false
end
end
if text_visible then
if not title_hf:getVisible() then
title_hf:setVisible(true)
text:setVisible(true)
end
else
if title_hf:getVisible() then
title_hf:setVisible(false)
text:setVisible(false)
end
end
until coroutine.yield()
end

VIDEO DE DEMOSTRACIÓN

A continuación se muestra el video de demonstración del sistema desarrollado:

http://www.youtube.com/watch?v=V_S3ulLdxEo&feature=youtu.be

El proyecto completo se puede descargar de:

Código de la aplicación en D'Fusion: immersion.rar

Código de la aplicación en Eclipse: race.rar

race/realidad_aumentada_para_cabinas_de_extraccion.txt · Última modificación: 2012/05/16 09:23 por jj.martinez60
Departamento de Ingeniería de Sistemas y Computación - Facultad de Ingeniería - Universidad de los Andes
CC Attribution-Noncommercial-Share Alike 3.0 Unported
Valid CSS Driven by DokuWiki Recent changes RSS feed Valid XHTML 1.0